NC14967. 六子冲
描述
六子冲是流传于中国民间的一类棋类游戏。由于这个游戏对环境的要求不高,孩子们大都是在光滑的地面或石板上画上方格,以石子或木棍、草节等为棋子,并有简单的比赛,可以锻炼脑力。
棋子只能停留在棋盘上的落子点,棋子只能在线上移动,棋子只能移动一步(即相邻落子点),每回合只能移动1个棋子。消灭对方棋子的方法只有一条,也很简单。那就是:二子打一子。即在棋盘上攻击方的2个棋子(2子必须相连并主动移动其中的1个)与被攻方的1个棋子皆处在一条直线上并相邻时,被攻方的这个棋子就被消灭。双方轮流走子,保护自己的棋子并消灭所有对方的棋子,直到最后胜利。
现为双方棋子赋予编号1~12。1~6号为黑方棋子,7~12号为白方棋子。其初始位置如下:
用两个整数,来代表走子方式。第一个数q代表棋子的编号,第二个数p,代表走子的方向。1<=q<=12,1<=p<=4,其中q的数字对应棋子的编号,p为1时向上走子,p为2时向下,3为向左,4为向右。给你n步走子方式,求最后棋盘的局面。
输入描述
数据有多组,处理到文件结束。
第一行一个数n,代表走子步数。
接下来n行,每行两个整数,第一个数q代表棋子的编号,第二个数p,代表走子的方向。
输出描述
每组数据第一行输出“#Case i:”并换行,其中i为测试用例编号,从1开始。
接着输出一个4*4的矩阵,代表棋盘局面的情况,4*4的矩阵代表棋盘上的4*4个棋位,矩阵的元素,即是棋盘上对应的棋子编号,没有棋子为0。输出的数字以3位的位宽输出。
示例1
输入:
8 7 3 6 1 12 4 1 1 12 2 2 1 10 2 4 1
输出:
#Case 1: 0 0 9 8 0 10 7 0 2 12 4 0 0 0 0 5
说明:
注意,输出的每一个棋子编号,都应是位宽为3的。最后的输出效果,每个数字都右对齐。如果网页显示有误或者描述不够清晰,请看下面:C++14(g++5.4) 解法, 执行用时: 4ms, 内存消耗: 520K, 提交时间: 2020-01-15 18:29:39
#include<bits/stdc++.h> using namespace std; int a[5][5]; int org[13][2]={ {0,0},{3,1},{4,1},{4,2},{4,3},{4,4},{3,4},{2,4},{1,4},{1,3},{1,2},{1,1},{2,1} }; int dx[]={0,-1,1,0,0}; int dy[]={0,0,0,-1,1}; inline int zy(int x){ return x!=0?(x>6)+1:0; } int die(int who,int x1,int x2,int x3,int x4){ x1=zy(x1); x2=zy(x2); x3=zy(x3); x4=zy(x4); if (x1&&x2&&x3&&!x4){ if (x1==x2&&x1!=x3){ if (who==1||who==2) return 3; } if (x2==x3&&x1!=x3){ if (who==2||who==3) return 1; } } if (x2&&x3&&x4&&!x1){ if (x2==x3&&x2!=x4){ if (who==2||who==3) return 4; } if (x3==x4&&x2!=x4){ if (who==3||who==4) return 2; } } return 0; } void kil(int x,int y){ int t; t=die(x,a[1][y],a[2][y],a[3][y],a[4][y]); a[t][y]=0; t=die(y,a[x][1],a[x][2],a[x][3],a[x][4]); a[x][t]=0; } void doit(int q,int dir){ int x=0,y=0; for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) if(a[i][j]==q){ x=i,y=j;break; } a[x][y]=0; a[x+dx[dir]][y+dy[dir]]=q; kil(x+dx[dir],y+dy[dir]); } int main(){ for(int i,j,n,cas=0;scanf("%d",&n)==1;){ memset(a,0,sizeof a); for(i=1;i<=12;i++) a[org[i][0]][org[i][1]]=i; for(int q,dir,t=1;t<=n;t++){ scanf("%d%d",&q,&dir); doit(q,dir); } printf("#Case %d:\n",++cas); for(i=1;i<=4;i++){ for(j=1;j<=4;j++) printf("%3d",a[i][j]); printf("\n"); } } }
C++11(clang++ 3.9) 解法, 执行用时: 5ms, 内存消耗: 384K, 提交时间: 2018-01-21 17:37:11
#include<bits/stdc++.h> using namespace std; int n,a[5][5]; int org[]={0,0,3,1,4,1,4,2,4,3,4,4,3,4,2,4,1,4,1,3,1,2,1,1,2,1}; int dx[]={0,-1,1,0,0},dy[]={0,0,0,-1,1}; int zy(int x){return x?(x>6)+1:0;} int die(int who,int x1,int x2,int x3,int x4){ x1=zy(x1); x2=zy(x2); x3=zy(x3); x4=zy(x4); if (x1&&x2&&x3&&!x4){ if (x1==x2&&x1!=x3) return who==3?0:3; if (x2==x3&&x1!=x3) return who==1?0:1; } if (x2&&x3&&x4&&!x1){ if (x2==x3&&x2!=x4) return who==4?0:4; if (x3==x4&&x2!=x4) return who==2?0:2; } return 0; } void kil(int x,int y){ a[die(x,a[1][y],a[2][y],a[3][y],a[4][y])][y]=0; a[x][die(y,a[x][1],a[x][2],a[x][3],a[x][4])]=0; } void doit(int q,int dir){ for (int i=1;i<=4;++i) for (int j=1;j<=4;++j) if (a[i][j]==q){ a[i][j]=0; a[i+dx[dir]][j+dy[dir]]=q; kil(i+dx[dir],j+dy[dir]); return; } } int main(){ for (int cas=0;scanf("%d",&n)==1;){ memset(a,0,sizeof a); for (int i=1;i<=12;++i) a[org[i*2]][org[i*2+1]]=i; for (int q,dir;n--;){ scanf("%d%d",&q,&dir); doit(q,dir); } printf("#Case %d:\n",++cas); for (int i=1;i<=4;++i,puts("")){ for (int j=1;j<=4;++j) printf("%3d",a[i][j]); } } }