列表

详情


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的。最后的输出效果,每个数字都右对齐。如果网页显示有误或者描述不够清晰,请看下面:
**0**0**9**8
**0*10**7**0
**2*12**4**0
**0**0**0**5
上面的‘*’对应输出样例中的空格。所有数据的结果,请按上面的格式输出。
在实际测试数据中,会存在让子的情况。即有可能出现一方玩家连续走子多次的情况。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

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

上一题