ACM模拟专题

您所在的位置:网站首页 多样例输入 ACM模拟专题

ACM模拟专题

2024-06-04 05:52| 来源: 网络整理| 查看: 265

1.1227-XTUOJ

题目描述

假设在一个XOY坐标的平面上,机器人一开始位于原点,面向Y轴正方向。 机器人可以执行向左转,向右转,向后转,前进四个指令。 指令为

LEFT:向左转RIGHT:向右转BACK:向后转FORWORD n:向前走n(1≤n≤100)个单位现在给你一个指令序列,求机器人最终的位置。

输入

样例的第一行是一个整数T(T≤20),表示样例的个数。 每个样例的第一行是一个整数N(1≤N≤1,000),表示指令的条数。 以后的N行,每行一条指令。

输出

每个样例输出两个整数,为坐标(x,y),之间用空格隔开。

样例输入 2 4 LEFT FORWORD 1 RIGHT FORWORD 1 2 BACK FORWORD 1 样例输出 -1 1 0 -1

考点:动作过程的模拟实现,找规律。

易错:字符读取数字,必须注意两位以及两位以上的数字

思路:审题,由题意得知是在坐标轴分析,题目的关键在于我们怎么求得机器人的朝向。根据三角函数很容易得出机器人转向的规律,由该规律直接模拟即可得出最终代码。

代码如下:

#include using namespace std; #define MAX 100 typedef char SString[MAX]; int main() { int T,N; SString str; scanf("%d",&T); while(T--) { int flag=0; int step; int x,y; x=y=0; scanf("%d",&N); getchar(); while(N--) { gets(str); if(str[0]=='L') flag--; if(str[0]=='R') flag++; if(str[0]=='B') flag+=2; if(str[0]=='F') { int length=strlen(str); if(length==9) step=str[8]-'0'; else if(length==10) step=(str[8]-'0')*10+str[9]-'0'; else step=100; if(flag%4==0) y+=step; if((flag-1)%4==0) x+=step; if((flag-2)%4==0) y-=step; if((flag-3)%4==0) x-=step; } } printf("%d %d\n",x,y); } return 0; }

2.1248-XTUOJ

Alice和Bob在玩骰子游戏,他们用三颗六面的骰子,游戏规则如下:

点数的优先级是1点最大,其次是6,5,4,3,2。三个骰子点数相同,称为"豹子",豹子之间按点数优先级比较大小。如果只有两个骰子点数相同,称为"对子",对子之间按点数优先级比较大小。其他情况称为"点子",点子按点数和比较大小。豹子比对子、点子大,对子比点子大,如果对子的点数优先级相同,就看剩余那个骰子的点数优先级。

现在给你Alice和Bob投掷骰子的情况,判断一下胜负情况。

输入

第一行输入一个整数K,表示游戏的次数。 以后每两行表示一个样例,第一行是Alice骰子的点数。第二行是Bob骰子的点数。

输出

如果是Alice赢,输出"Alice",如果是Bob赢,输出"Bob",否则输出"Draw"。

样例输入 3 1 1 1 6 6 6 2 1 2 4 5 4 4 5 6 6 5 4 样例输出 Alice Bob Draw

考点:过程的模拟实现。

易错:题意的理解--点数的优先级。

解题思路:

      理解题目,题目要求我们去实现这个过程。要模拟这个过程,必须弄清楚这个过程有哪些步骤,然后用函数分别实现这些步骤,这样也方便调试。由题可知,我们要实现下列这些函数功能。

(1)点数优先级的比较。

(2)豹子对子点子的判断。

(3)豹子同豹子,点子同点子以及对子同对子之间的比较。其中,对子同对子的比较比较容易出错。

      想好这些逻辑以后,我们开始实现这个过程即可。注意,两个对子最多要比较两次数字优先级,如果在敲代码之前没有注意到这点,就会让整个程序出错。

代码如下:

#include using namespace std; int flag; int Scan(int a[]) { if(a[0]==a[1]&&a[1]==a[2]) return 3; else if((a[0]==a[1])||(a[0]==a[2])||(a[1]==a[2]))return 2; else return 1; } void num_judge(int a,int b) { if(a==1||b==1) { if(a==1&&b==1) flag=3; else if(a==1) flag=1; else flag=2; } else if(a>b) flag=1; else if(ab[1]) flag=1; else flag=2; } } int main() { int a[5],b[5]; int K; scanf("%d",&K); while(K--) { int judge_1,judge_2; for(int i=0; i=q[i]) flag++; else { p[num_p]=q[i]; num_p++; } } if(flag==n) break; turnover++; num_q=0; num_change(p,num_p); } printf("%d\n",turnover); } return 0; }

方法二:

#include using namespace std; //vectorp; #define MAX 1010 int main() { int n; int a[MAX]; bool ans[MAX]; while(scanf("%d",&n)!=EOF) { int flag=0; int turnover=0; memset(ans,false,sizeof(ans)); for(int i=0; i=0; i--) { if((flag>=a[i])&&!ans[i]) { flag++; ans[i]=true; } } if(flag==n) break; turnover++; } printf("%d\n",turnover); } return 0; }

4.1258-XTUOJ

编写一个程序,将1 ~ n 2  按行依次填入n×n 的矩阵,执行若干条行或者列的循环移动的指令,再将数字按行依次取出。

指令如下:

指令含义L x yx行循环左移y次R x yx行循环右移y次U x yx列循环上移y次D x yx列循环下移y次 输入

第一行是一个整数K,表示样例的个数。 每个样例的第一行是两个整数n(1≤n≤10) 和m(1≤m≤1000) ,分别表示矩阵的大小和指令的条数。 以后的m行是m条指令,矩阵的行列按1开始计数,指令满足1≤x≤n,1≤y≤n−1 。

输出

每行输出一个样例的结果,数字之间用一个空格隔开,行末无空格。

样例输入 4 3 1 L 1 1 3 1 R 1 1 3 1 U 1 1 3 1 D 1 1 样例输出 2 3 1 4 5 6 7 8 9 3 1 2 4 5 6 7 8 9 4 2 3 7 5 6 1 8 9 7 2 3 1 5 6 4 8 9

考点:过程模拟,数据的循环移动。

易错:循环移动规律。

思路:

      理清题意。题目的实质是,找出数据循环移动n位后所在的位置,我们就依次我出发点,找出一定规律。先来看向右移动。我们取题目中一个样例分析可知,如果数据a在数据中的初位置为flag,那么向右移动b位后的位置为(flag+b)%n,其中,n为行数目。经分析可知,向下移动和此规律是一致的。那么我们再来分析向左移动。同样是由特殊到一般的规律,取题中样例分析:初始flag=0,n=3;

flag      b      实际位置

-1          1            2

-2          1            1

-3          1            0

       分析到这里,实际上我们可以得出结论了,但是还有一种更好的思路,我们可以假设,在flag=0的位置前面,仍旧有三个位置,检验一下,flag=0,左移一位,刚好到2,继续左移,到1,继续左移,到0,和我们已知的规律是一致的,由此,我们得出左移的规律:

b=b%n;//左移4位实质上和左移一位是相同的,所以才有了这个式子。

flag'=(n+flag-b)%n;

至此,这个问题也解决一半了。那么对于该题所用的存储结构,自然想到用二维数组。

拓展:

       在这个题目中,楼主又发现了“新大陆”。楼主刚接触STL不就,想试试这个STL的“威力”,最后才让楼主明白,这是在作死。

(1)Vector的初始化必须用Push_back(),不可以调用scanf函数直接存储。

(2)Vector一维数组不可以直接赋值给二维的Vector。但是可以用整型数组赋值。

如:

vectorP[MAX]

vectorp;

for(int i=0;i



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3