列表

详情


NC220057. 井字棋残局

描述

井字棋,是一种在3*3格子上进行的连珠游戏,和五子棋类似,由于棋盘一般不画边框,格线排成井字故得名。

游戏需要的工具仅为纸和笔,然后由分别代表X和O的两个游戏者轮流在格子里留下标记(先手者为X),任意三个标记形成一条直线,则为获胜。

 

坤坤觉得这个游戏很有趣,就想要提高一下难度,所以先随机在3*3的格子上生成了N个棋子形成残局(棋子位置保证不重复),然后请来了云哥对弈,本来以为会有一场腥风血雨的厮杀,谁承想云哥看完棋局后微微一笑,说出了这场残局的最终结果。

你知道结果如何吗?
(PS:假设两人都很聪明)

输入描述

输入一行一个正整数t,表示棋局数。

对于每场棋局都有:

输入一行一个非负数N,表示随机生成的棋子数,

输入N行,每行包含两个元素xi,yi,表示生成棋子的行和列。

i为奇数时表示生成的X的坐标,i为偶数时表示生成的O的坐标。

(0<=N<=9)

(对于30%的数据,1<t<100)

(对于70%的数据,1<t<1000)

(对于100%的数据,1<t<10000)

输出描述

对于每场棋局,输出最终结果,结果有三种情况。

X赢输出“X”,O赢输出“O”,平局输出“-1”.

示例1

输入:

1
0

输出:

-1

说明:

没有生成棋局的情况下,无人可以获得最终的胜利

示例2

输入:

1
4
3 3
2 2
3 2
1 1

输出:

X

说明:

第一次X生成在了(3,3)的位置
第二次O生成在了(2,2)的位置
第三次X生成在了(3,2)的位置
第四次O生成在了(1,1)的位置
此时轮到X,X只需要下在(3,1)的位置即可获胜
所以输出“X”

原站题解

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

Java(javac 1.8) 解法, 执行用时: 195ms, 内存消耗: 21396K, 提交时间: 2021-04-13 08:52:14

import java.util.Scanner;

public class Main {
	public static int map[];
	public static boolean check(int x){
		for(int i=0;i<3;i++){
			if(map[i*3+0]+map[i*3+1]+map[i*3+2]==3*x
			||map[3*0+i]+map[3*1+i]+map[3*2+i]==3*x)return true;
		}
		return map[0]+map[4]+map[8]==3*x||map[2]+map[4]+map[6]==3*x;
	}
	public static int fine(int k){
		if(k>=10){
			return check(1)?1:check(-1)?-1:0;
		}else {
			int ping=0,shu=0,ying=0;
			int playr=k%2==1?1:-1;
			for(int i=0;i<9;i++){
				if(map[i]==0){
					map[i]=playr;
					if(check(playr))ying++;
					else {
						int test=fine(k+1);
						if(test==playr)ying++;
						else if(test==0)ping++;
						else shu++;
					}
					map[i]=0;
				}
			}
			return ying>0?playr:(ping>0?0:-playr);
		}
	}
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int t=sc.nextInt();
		while(t-->0){
			int n=sc.nextInt();
			map=new int[9];
			for(int i=1;i<=n;i++){
				int x=sc.nextInt();
				int y=sc.nextInt();
				map[(x-1)*3+y-1]=i%2==1?1:-1;//X=1;O=-1;
			}
			int ans=fine(n+1);
			System.out.println(ans==1?"X":ans==-1?"O":"-1");
		}
	}
}

C++(clang++ 11.0.1) 解法, 执行用时: 18ms, 内存消耗: 424K, 提交时间: 2022-11-05 22:09:52

#include <bits/stdc++.h>
using namespace std;
int t,n,g[10];
int check(int u){
	if(g[0]+g[4]+g[8]==u*3||g[2]+g[4]+g[6]==u*3)return 1;
	if(g[0]+g[1]+g[2]==u*3||g[3]+g[4]+g[5]==u*3||g[6]+g[7]+g[8]==u*3)return 1;
	if(g[0]+g[3]+g[6]==u*3||g[1]+g[4]+g[7]==u*3||g[2]+g[5]+g[8]==u*3)return 1;
	return 0;
}
int dfs(int st){
	if(st==10){
		if(check(1))return 1;
		if(check(-1))return -1;
		return 0;
	}else{
		int win=0,lose=0,draw=0;
		int t=st&1?1:-1;
		for(int i=0;i<9;i++){
			if(!g[i]){
				g[i]=t;
				if(check(t))win++;
				else{
					int p=dfs(st+1);
					if(p==t)win++;
					else if(!p)draw++;
					else lose++;
				}g[i]=0;
			}
		}
		if(win)return t;
		if(draw) return 0;
		return -t;
	}
}
int main(){
	cin>>t;
	while(t--){
		for(int i=0;i<10;i++){
			g[i]=0;
		}
		cin>>n;
		for(int i=1;i<=n;i++){
			int x,y;
			cin>>x>>y;
			x--,y--;
			if(i%2==0)g[x*3+y]=-1;
			else g[x*3+y]=1;
		}int ans=dfs(n+1);
		if(ans==1)cout<<"X"<<endl;
		else if(ans==0)cout<<"-1"<<endl;
		else cout<<"O"<<endl;
	}
	return 0;
}

上一题