1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 网易互娱实习生招聘游戏研发工程师笔试第二场(一起消消毒)

网易互娱实习生招聘游戏研发工程师笔试第二场(一起消消毒)

时间:2023-06-12 02:40:12

相关推荐

网易互娱实习生招聘游戏研发工程师笔试第二场(一起消消毒)

题意分析:

(1)题目是模拟开心消消乐的游戏逻辑,当交换两个相邻的图片时,如果交换后的面板中有连续的三个以上的相同的图片(拍成行或列),那么这些排列成行或列的相同的图形将消失,上面的图形将下落填充中间的空白,下落后有可能再次出现可消除的情况,于是同以上步骤,一直到最后没有可消除为止,求这次交换操作一共可消去多少个图形。

(2)题目对游戏的原型进行了简化:即消去一部分图形之后,没有新的图形产生,下落完成后,空余的部分用空白替代,图形用字符代替。我们可以先从第一个非‘.’的字符出发,作如下操作:从这个字符开始左右扫描,找出这一行是否有连续的三个以上(包括本字符)字符和本字符相同,设这一可消行的左右边界为(b,d);如没有连续的三个及以上,则从这个字符上下开始扫描。如找到可消列,设列的边界为(a,c)

(3)注意:这里并非找到连续的三个及以上相同的字符就立即消除,而是要顺着这个可消行(列)依次向上下(左右)继续搜索,找出在这个行(列)上其他的字符为中心上下扩展搜索的可消除列(行)的字符,称为"枢轴",见下图:

(4)如图:找到可消区域的枢轴之后,沿着枢轴找到上下边界(a,c),左右边界(b,d),然后删除这个边界内的图形;图一是正确的消除,反之,如果一开始找到连续的三个及以上的图形就删除,就会导致图二的错误,会由于消除枢轴之后,右边一列下落之后缺少一个,不能消除。

(5)设枢轴为arr[x][y],按照(4)消除之后,就需要将在x行以上(a,c)列之间的列向下移动一个位置,y列中空格上面的字符集体向下移动(d-1-b)个位置

(6)消除并移动之后,就会出现新的面板状态,这时有可能新的面板状态中由于图形的移动会出现新的可消行(列),于是我们又需要从头开始检索,如果存在可消行(列),就执行以上的重复步骤;反之,就开始检索下一个位置。这就是典型的回溯

可能坑点:

(1)没有找到枢轴,只找到可消行列就开始消除

(2)一定要注意可消行列的边界,本算法中边界不包括a、c、b、d,很容易不注意就弄错边界

(3)回溯的条件是:这一轮没有找到可消的行列,反应在数字上就是连续行、列相同的图形个数分别小于3,注意一定要是分别小于3!!!这里很容易出错。

(4)消除的时候下落距离要弄清

#include <iostream>#include <stdio.h>using namespace std;int N,M;char arr[20][20];int res=0;void cal(){for(int i=0;i<N;i++){for(int j=0;j<M;j++){//遇到非空格字符的时候才开始判断if(arr[i][j]!='.'){int x=i,y=j;//最终消除区域的中心int a=i,b=j,c=i,d=j;int sum=0;int temp=0;//先开始纵向搜索while((--a)>=0&&arr[a][j]==arr[i][j])temp++;while((++c)<N&&arr[c][j]==arr[i][j])temp++;//若纵向搜索可找到消除的列if(temp>=2){sum+=temp;temp=0;int maxum=0;//开始在这个纵向列上以每个字符为中心开始横向搜索for(int k=a+1;k<=c;k++){int cnt=0;int b1=j,d1=j;while((--b1)>=0&&arr[k][b1]==arr[i][j])cnt++;while((++d1)<M&&arr[k][d1]==arr[i][j])cnt++;//若横向搜索可找到消除的行if(cnt>=2&&cnt>maxum){maxum=cnt;//更新中心点x=k;y=j;//更新左右边界b=b1;d=d1;}}sum+=maxum;}else//若纵向搜索找不到消除的列{temp=0;a=i,b=j,c=i,d=j;//开始重新横向搜索while((--b)>=0&&arr[i][b]==arr[i][j])temp++;while((++d)<M&&arr[i][d]==arr[i][j])temp++;//若横向搜索可找到消除的行if(temp>=2){sum+=temp;temp=0;int maxum=0;//开始在这个横向行上以每个字符为中心开始纵向搜索for(int k=b+1;k<d;k++){int cnt=0;int a1=i,c1=i;while((--a1)>=0&&arr[a1][k]==arr[i][j])cnt++;while((++c1)<N&&arr[c1][k]==arr[i][j])cnt++;//若纵向搜索可找到消除的列if(cnt>=2&&cnt>maxum){maxum=cnt;//更新中心点x=i;y=k;//更新上下边界a=a1;c=c1;}}sum+=maxum;}}//若符合消除的条件if(sum>=2){res+=sum;sum=0;res++;//若纵向上有消除的列,则消除后合并if(c-a>=3){for(int e=a;e>=0;e--)arr[e+c-1-a][y]=arr[e][y];for(int e=0;e<c-a-1;e++)arr[e][y]='.';}//若横向上有消除的行,则消除后合并if(d-b>=4){for(int e=b+1;e<d;e++){for(int f=x-1;f>=0;f--)arr[f+1][e]=arr[f][e];arr[0][e]='.';}}//开始向下回溯cal();}}}}}int main(){int S,x0,y0,x1,y1;cin>>S;while(S--){cin>>N>>M;for(int i=0;i<N;i++){for(int j=0;j<M;j++)cin>>arr[i][j];}scanf("%d %d %d %d",&x0,&y0,&x1,&y1);char temp=arr[x0][y0];arr[x0][y0]=arr[x1][y1];arr[x1][y1]=temp;cal();printf("%d\n",res);res=0;}return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。