网易游戏实习招聘

推箱子

是一款经典游戏。如图所示,灰色格子代表不能通过区域,蓝色方格是箱子,黑色圆形代表玩家,含有圆点的格子代表目标点。


规定以下规则:

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;
}


不知道为什么会错。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值