推箱子
是一款经典游戏。如图所示,灰色格子代表不能通过区域,蓝色方格是箱子,黑色圆形代表玩家,含有圆点的格子代表目标点。
规定以下规则:
1、一局游戏中只会有一个箱子,一个玩家和一个目标点。
2、通过方向键控制玩家移动。
3、图中的灰色格子代表墙壁,玩家与箱子都不能通过。
4、推到墙壁的箱子,就无法再将箱子推离墙壁,因为玩家无法到达箱子靠墙壁的一侧去推箱子。也就是说箱子只能以“被推”的方式被移动,不是以“被拉”的方式被移动。但如果玩家将箱子推至墙壁后,垂直墙壁的两侧没有阻碍物,则玩家可以朝这两个不同的方向推移箱子。如果箱子进入角落,就没有办法再推动这个箱子了。
5、玩家是不能走出场景的。玩家推着箱子到达场景边缘,如果继续点击使玩家和箱子向墙壁前进的方向键,箱子和人都会保持不动。玩家的前进方向上如果有墙壁,也是不能前进的。但是这些点击都视为合理的输入。
6、箱子一旦到达目标点,就不能再移动了。但这时,玩家仍然可以在场景内自由行动。如果继续尝试推箱子,那么玩家将会和箱子一起保持在原地不动。
现在,给出一种方向键的点击方案,请判断,这种方案是否能使箱子最终停在目标点上。为了方便表示,我们以0代表空白格子,以4代表不能通过区域,以1代表玩家,以3代表箱子,以2代表目标点。
输入
第一行数据包含三个整数,N,M,S。其中,N(0 < N <= 100)代表格子的宽度,M(0 < M <= 100)代表格子的高度,S(0 < S <= 200)代表测试点的个数。
接下来的M行,每行都会有N个字符,描述当前的盘面。
接下来的S行,每行都代表一个测试点。每行都以一个整数T(0 < T <= 10000)开头,接下来是一个空格和T个字符。这T个字符仅由d,u,l,r这四个字母组成,分别代表了敲击向下,向上,向左,向右的方向键。
输出
对于每个测试点,输出最后箱子是否在目标点上。如果是,输出YES,如果不是,则输出NO。
5 4 3 00000 13000 00200 00000 4 rurd 6 urdldr 6 rrrurd
样例输出 yes yes no
#include <iostream>
#include <vector>
#include <map>
using namespace std;
int main(){
int n, m , s;
cin>>n>>m>>s;
vector<vector<int> > bd(m, vector<int>(n));
int sy, sx;
int ey, ex;
int by, bx;
for(int i = 0; i<m; i++){
for(int j = 0; j<n; j++){
char t; cin>>t; t-='0';
if(t==1) {sy = i, sx = j;}
else if(t==2) {ey = i, ex = j;}
else if(t==3) {by = i, bx = j;}
bd[i][j] = t!=4;
//1: no brick, 0:brick
}
}
for(int i = 0; i<s; i++){
int cnt; char c;
cin>>cnt;
int x = sx, y = sy;
int tx = sx, ty = sy;
int rx = bx, ry = by;
int j;
for(j = 0; j<cnt; j++){
//cout<<y<<","<<x<<endl;
cin>>c;
switch(c){
case 'r': tx = x+1; ty = y; break; //@error 1: 后面一句话ty=y忘记写了,因为tx,ty都有可能是脏数据而和x,y不同步。下同
case 'u': ty = y-1; tx = x; break;
case 'd': ty = y+1; tx = x; break;
case 'l': tx = x-1; ty = y; break;
break;
}
if(tx <0 || ty <0 || tx>= n || ty>=m || bd[ty][tx] == 0) continue;
if(ty == ry && tx == rx){
if(ty == ey && tx == ex) continue;
int xx = 2*tx - x, yy = 2*ty - y;
if(xx <0 || yy <0 || xx>= n || yy>=m || bd[yy][xx] ==0) continue;
rx = xx, ry = yy;
}
x = tx, y = ty;
}
if(rx!=ex || ry!=ey) {cout<<"NO"<<endl;}
else cout<<"YES"<<endl;
}
return 0;
}
很水的一道题,关键是记录箱子坐标(bx, by), 人坐标(sx,sy), 然后用vector<vector<>>记录地图(有无墙壁) 但是在人移动时,需要临时坐标tx,ty和xx,yy,计算临时坐标的时候注意了(见注释error 1)
井字棋
井字棋,又称为井字游戏、井字过三关等,是种纸笔游戏。其具体玩法为:
两个玩家,一个打圈(O),一个打叉(X),轮流在3乘3的格上打自己的符号,最先以横、直、斜连成一线则为胜。当9个格子画满,双方均无法取胜时,则为和局。当有玩家取胜或者下成平局后,比赛结束。
假设每次X方均为先手,给出一个局面,请你判断这个局面是否合法,如果局面合法,则判断当前局面是否是比赛结束局面,如果是,则判断当前局面是X方胜利,O方胜利或者是平局。如果局面暂时未分胜负,则判断下一个下棋的选手下完一步后(假设采用最优策略)能否取胜。
输入
每个输入数据包含多个测试点。
第一行为测试点的个数S <= 2000。之后是S个测试点的数据。
每个测试点的数据包括3行,用于描述整个棋盘。每行包含一个长度为3的字符串,取值范围为{'_', 'O', 'X'},其中'_'表示该格子为空,'X'表示该格被先手者占领,'O'表示该格被后手者占领。
每个测试点之间会有一个空行相隔。
输出
对于每个测试点,对应的结果输出一行。
如果局面非法,则输出"Invalid"。
否则如果局面是比赛结束局面,X取胜则输出"X win", O取胜则输出"O win", 如果是平局则输出"Draw"。
如果局面合法并且不是比赛结束的局面,则判断下一个下棋的选手下完一步后能否取胜,如果可以,则输出"Next win", 否则输出"Next cannot win"。
注意,所有的结果输出均不带引号。
样例提示
第一个例子,因为X先下,所以该局面不可能出现。
第二个例子,为结束局面,X取胜。
第三个例子,全部格子下完,双方均无法取胜,平局。
第四个例子,局面未分胜负,下一个下的是X,可以取胜。
第五个例子,局面未分胜负,下一个下的是O,无论下到哪一个格子均无法取胜。
5 __O _XO ___ XXX ___ OO_ XXO OOX XXO X_X OO_ ___ XO_ XX_ __O
样例输出
#include <iostream>
using namespace std;
char t[3][3];
#define MIN -999
int findline(char c){
int mcnt = -1;
for(int i = 0 ; i<3; i++){
int ijcnt = 0, jicnt = 0;
for(int j = 0; j<3; j++){
if(t[i][j]==c) ijcnt++;
else if(t[i][j]!='_') ijcnt=MIN;
if(t[j][i]==c) jicnt++;
else if(t[j][i]!='_') jicnt=MIN;
}
mcnt = max(mcnt, ijcnt);
mcnt = max(mcnt, jicnt);
}
int iicnt = 0, jjcnt = 0;
for(int i = 0; i<3; i++){
if(t[i][i] ==c) iicnt ++;
else if(t[i][i] !='_') iicnt=MIN;
}
for(int i = 0; i<3; i++){
if(t[i][2-i] ==c) jjcnt ++;
else if(t[i][2-i] !='_') jjcnt=MIN;
}
mcnt = max(mcnt, iicnt);
mcnt = max(mcnt, jjcnt);
return mcnt;
}
int main(){
int n; cin>>n;
for(int c = 0; c<n; c++){
int cx = 0, co = 0;
for(int i = 0; i<3; i++){
for(int j = 0; j<3; j++){
char ch ; cin>>ch;
//cout<<ch<<":"<<endl;
if(ch =='X') cx ++;
else if(ch =='O') co ++;
t[i][j] = ch;
}
}
if(co>cx || cx>co+1) {cout<<"Invalid"<<endl; continue;}
int x = findline('X'), y = findline('O');
if(x==3 && y==3) {cout<<"Invalid"<<endl; continue;}
if(x==3) {cout<<"X win"<<endl;continue;}
if(y==3) {cout<<"O win"<<endl;continue;}
if(co + cx == 9 || x<0 && y<0) {cout<<"Draw"<<endl;continue;}
if(cx==co){
if(x == 2) cout<<"Next win"<<endl;
else cout<<"Next cannot win"<<endl;
}
else {
if(y == 2) cout<<"Next win"<<endl;
else cout<<"Next cannot win"<<endl;
}
}
return 0;
}
不知道为什么会错。