news 2026/5/17 0:10:34

UVa 141 The Spot Game

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
UVa 141 The Spot Game

题目分析

The Spot Game\texttt{The Spot Game}The Spot Game是一个基于N×NN \times NN×N棋盘的游戏,双方轮流执行操作,操作包括:

  • 在空白格子中放置一个黑子(用 “+” 表示);
  • 从棋盘上移除一个已有的黑子(用 “-” 表示)。

游戏规则如下:

  • 如果当前棋盘状态(或其旋转90°90°90°180°180°180°后的状态)在之前的游戏过程中已经出现过,则当前玩家立即输掉游戏,对方获胜;
  • 游戏最多进行2N2N2N步;
  • 如果在2N2N2N步后仍未出现重复状态,则游戏平局。

输入包含多组游戏,每组游戏的第一行为棋盘大小NNN2≤N≤502 \leq N \leq 502N50),接下来是2N2N2N行操作,每行包含坐标(x,y)(x, y)(x,y)和操作符+-。输入以000结束。

输出应指出获胜的玩家和获胜的步数,或声明游戏平局。

解题思路

核心问题

我们需要高效地检测棋盘状态是否重复(包括旋转后的状态)。由于棋盘最大可达50×5050 \times 5050×50,直接表示状态矩阵并比较的复杂度较高,但我们可以将状态编码成字符串进行存储和比较。

状态编码

我们可以用一个长度为N×NN \times NN×N的字符串表示棋盘状态:

  • ‘1’表示该位置有黑子;
  • ‘0’表示该位置为空。

每次操作后,更新对应的字符。

旋转处理

题目要求判断当前状态是否与之前任一状态在旋转0°0°90°90°90°(顺时针)、90°90°90°(逆时针)或180°180°180°后相同。因此,我们需要编写函数,分别生成当前状态的三种旋转状态。

为了便于比较,我们始终将旋转后的状态也编码为字符串,并存储到集合中。

查找重复

使用哈希表(如map<string, int>)存储所有出现过的状态(包括旋转后的状态),值为首次出现时的步数。

每步操作后,生成当前状态的四个等价状态(原状态 + 三种旋转),检查它们是否已经在哈希表中:

  • 如果存在,则当前玩家输,对方获胜;
  • 否则,将这四个状态插入哈希表,记录当前步数。

时间复杂度

每一步需要生成四个字符串,长度均为N2N^2N2,最多2N2N2N步,因此总时间复杂度约为O(N3)O(N^3)O(N3),在N≤50N \leq 50N50时是可接受的。

代码实现说明

以下代码使用C++\texttt{C++}C++编写,主要步骤包括:

  1. 读取NNN,若为 0 则结束;
  2. 初始化状态字符串和哈希表;
  3. 循环处理2N2N2N步操作:
    • 更新棋盘状态;
    • 检查当前状态是否已出现;
    • 生成旋转状态并插入哈希表;
  4. 根据是否出现重复状态输出结果。

参考代码

// The Spot Game// UVa ID: 141// Verdict: Accepted// Submission Date: 2016-01-20// UVa Run Time: 0.003s//// 版权所有(C)2016,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;stringrotateCW90(string matrix,intn){string newMatrix;for(inti=1;i<=n;i++)for(intj=1;j<=n;j++)newMatrix+=matrix[(n-1)*n+(i-1)-(j-1)*n];returnnewMatrix;}stringrotateCCW90(string matrix,intn){string newMatrix;for(inti=1;i<=n;i++)for(intj=1;j<=n;j++)newMatrix+=matrix[(n-1)-(i-1)+(j-1)*n];returnnewMatrix;}stringrotate180(string matrix){reverse(matrix.begin(),matrix.end());returnmatrix;}intmain(){intn,x,y;string line;map<string,int>steps;while(cin>>n,n){intwinner=0,move=0;string matrix=string(n*n,'0');steps.clear();for(inti=1;i<=2*n;i++){cin>>x>>y;getline(cin,line);if(winner>0)continue;matrix[(x-1)*n+(y-1)]=(line.find('+')!=line.npos)?'1':'0';if(steps.find(matrix)!=steps.end()){winner=(steps[matrix]%2==1)?2:1;move=i;}string newMatrix[4]={matrix,rotateCW90(matrix,n),rotateCCW90(matrix,n),rotate180(matrix)};for(intj=0;j<4;j++)if(steps.find(newMatrix[j])==steps.end())steps.insert(make_pair(newMatrix[j],i));}if(winner==0)cout<<"Draw\n";elsecout<<"Player "<<winner<<" wins on move "<<move<<'\n';}return0;}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 20:18:05

翱捷科技 Android/Linux 芯片平台功耗软件工程师:核心技术解析与实战

翱捷科技股份有限公司 Android/Linux芯片平台功耗软件工程师 (MJ000299) 职位信息 岗位职责 在公司自研芯片平台(SoC)上,负责: 1. Linux系统clock,idle,CPU freq,thermal,battery,charger等底层驱动开发。 2. Android thermal/charger health/power hint等HAL的开发。…

作者头像 李华
网站建设 2026/5/8 20:18:10

LeetCode 3650.边反转的最小路径总成本:Dijkstra算法

【LetMeFly】3650.边反转的最小路径总成本&#xff1a;Dijkstra算法 力扣题目链接&#xff1a;https://leetcode.cn/problems/minimum-cost-path-with-edge-reversals/ 给你一个包含 n 个节点的有向带权图&#xff0c;节点编号从 0 到 n - 1。同时给你一个数组 edges&#xf…

作者头像 李华
网站建设 2026/5/15 17:43:51

实测缩短70%课件制作时间:这款AIPPT工具就是老师的大救星

实测缩短70%课件制作时间&#xff1a;ChatPPT引领教学效率革命 实测数据显示&#xff0c;使用ChatPPT制作课件&#xff0c;基础构建时间可缩短70%以上&#xff0c;这不是夸张&#xff0c;而是众多教育工作者的真实反馈。在2026年的今天&#xff0c;课件制作正经历着一场由AI驱动…

作者头像 李华
网站建设 2026/5/16 20:57:14

CoDeSys入门实战一起学习(二十):布尔、整型、实数、字符串、时间5大类标准数据类型详解(附实战案例)

写CoDeSys程序的第一步&#xff0c;必然是声明变量/常量&#xff0c;而所有声明都离不开数据类型。CoDeSys的标准数据类型完全遵循IEC61131-3标准&#xff0c;共分为布尔、整型、实数、字符串、时间5大类&#xff0c;是所有PLC程序的“基础积木”。很多新手容易踩坑&#xff1a…

作者头像 李华
网站建设 2026/5/8 21:11:26

KingbaseES数据库瓶颈排查实战指南:从实例到语句的全维度解析

在高并发、海量数据的业务场景下&#xff0c;数据库性能直接决定了应用系统的响应速度和稳定性&#xff0c;而瓶颈排查则是性能调优的核心前提——只有精准定位问题根源&#xff0c;才能避免盲目调参、优化无效的内耗。KingbaseES作为国产数据库中的优秀代表&#xff0c;在政务…

作者头像 李华