点击打开链接
题目意思: 有两个人在玩游戏,游戏是在长为N的正方形棋盘,上面是由一序列格子组成,现在输入一些操作指令由两个人轮流操作,每一次操作对应的棋盘上面会有一个状态,如果当前的状态或这个状态旋转90或180度而来的状态以及出现过,那么这个人就输,如果当所有指令操作完以后还没分胜负就是平局
解题思路: set+状态判重即可,注意对set里面放结构体的使用,重载<号。
1:我们知道对于set和map而言,插入的数据默认是那些常见的数据,由于set和map的内部实现是有一个cmp函数(使用小于号)的。那么如果我们要将结构体插入set或map里面,那么我们就应该在结构体里面重载一个小于号函数。(对于这一题,由于我么只是想知道到底有没有存在这个状态对于是否按照什么顺序我们不用关心,那么我么只须重载了小于<函数就可以了,并不用纠结怎么重载)
2:对于状态的判重,我么知道只要将初始状态一直向右旋转,那么最后还是会回到最初的状态,所以我么只要能够找到向右旋转90度后的状态和初始状态的关系,然后没得到一个状态就去判断,如果初始状态和由它旋转而来的状态都不再set里面,那么就把这些状态插入set。注意这里必须等到所有的都不再set里面再一起插入
代码:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <stack>
#include <queue>
#include <cmath>
#include <set>
using namespace std;
#define MAXN 55
int n;
struct state{//状态结构体
int State[MAXN][MAXN];
//自定义重载<(定义为友元)
friend bool operator<(const state &a,const state &b){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){//以第一个值作为判断基准
if(a.State[i][j] < b.State[i][j]) return true;
if(a.State[i][j] > b.State[i][j]) return false;
}
}
}
}sta;
set<state>s;//创建set容器s
//处理
int solve(){
state tmp1 , tmp2 , tmp3;
if(s.find(sta) != s.end()) return 1;
else{
//sta右旋转90得到tmp1
memset(tmp1.State , 0 , sizeof(tmp1.State));
for(int i = 1 ; i <= n ; i++){
for(int j = 1 ; j <= n ; j++)
tmp1.State[j][n-i+1] = sta.State[i][j];
}
if(s.find(tmp1) != s.end()) return 1;//如果存在返回1
//tmp1旋转90得到tmp2
memset(tmp2.State , 0 , sizeof(tmp2.State));
for(int i = 1 ; i <= n ; i++){
for(int j = 1 ; j <= n ; j++)
tmp2.State[j][n-i+1] = tmp1.State[i][j];
}
if(s.find(tmp2) != s.end()) return 1;//如果存在返回1
//tmp2旋转90得到tmp3
memset(tmp3.State , 0 , sizeof(tmp3.State));
for(int i = 1 ; i <= n ; i++){
for(int j = 1 ; j <= n ; j++)
tmp3.State[j][n-i+1] = tmp2.State[i][j];
}
if(s.find(tmp3) != s.end()) return 1;//如果存在返回1
//最后插入set(如果前面插入存在导致错误的判断)
s.insert(sta) ; s.insert(tmp1);
s.insert(tmp2) ; s.insert(tmp3);
}
return 0;
}
int main(){
//freopen("input.txt" , "r" , stdin);
int G[110][2];
char c[110];
int flag;//判断是否是平局还是某一方赢
while(scanf("%d" , &n) && n){
s.clear();
memset(sta.State , 0 , sizeof(sta.State)) ; flag = 0;
for(int i = 1 ; i <= 2*n ; i++)
scanf("%d %d %c" , &G[i][0] , &G[i][1] , &c[i]);
for(int i = 1 ; i <= 2*n ; i++){
if(c[i] == '+') sta.State[G[i][0]][G[i][1]] = 1;
if(c[i] == '-') sta.State[G[i][0]][G[i][1]] = 0;
if(i > 1){
if(solve()){
if(i % 2 != 0) printf("Player 2 wins on move %d\n" , i);//注意赢家是谁
else printf("Player 1 wins on move %d\n" , i);
flag = 1 ; break;
}
}
else s.insert(sta) ;//第一个状态直接插入即可
}
if(!flag) printf("Draw\n");
}
return 0;
}
分享到:
相关推荐
标题中的"UVaOJ-401(Palindromes)"表明这是一个关于解决UVa Online Judge(UVa OJ)上编号为401的编程挑战,该挑战的主题是"Palindromes",即回文串。回文串是指一个字符串无论从前读到后还是从后读到前都是相同的,...
### Uva 1510 - Neon Sign #### 问题背景与描述 在题目“Uva 1510 - Neon Sign”中,我们面对的是一个霓虹灯招牌设计问题。该霓虹灯招牌由一系列位于圆周上的角点组成,并通过发光管连接这些角点。发光管有两种...
4. **UVA152 - The Stock Maximal Sequence**:此题属于动态规划,要求找到股票价格序列中的最大收益。关键在于找到合适的状态转移方程,考虑买卖股票的最佳时机。 5. **UVA107 - Robot Walk**:该题考察图论和深度...
【标题】"uva705-Slash-Maze-.rar_Slash_uva705" 指向的是一个在UVa Online Judge (UVa OJ) 上提交并通过的编程问题,具体为问题编号705,名为"Slash Maze"。这个压缩包很可能包含了该问题的解决方案源代码。 ...
开源项目-codingsince1985-UVa#uva-online-judge-solutions-in-golang.zip,两年来每天都在解决一个uva在线裁判问题,算起来…
《UVA133 - 救济金发放问题:The Dole Queue》 在计算机科学领域,算法是解决问题的关键工具,特别是在处理复杂数据结构和优化问题时。UVA(University of Virginia)在线判题系统提供了丰富的算法题目供程序员挑战...
"Algorithm-UVA-Solutions-in-Python.zip"这个压缩包文件正是针对UVA竞赛中问题的Python 3解决方案集合。 Python作为一门易学且功能强大的编程语言,因其简洁的语法和丰富的库支持,成为了许多算法爱好者和开发者的...
《UVA532 Dungeon Master:解密游戏编程的深度探索》 在计算机科学与编程领域,UVA(University of Virginia)在线判题系统是一个深受程序员喜爱的平台,它提供了丰富的算法题目供学习者挑战。其中,编号为532的...
"tpcw-nyu-uva-client 客户端"是一个专为TPCW(Transaction Processing Performance Council Workloads)设计的应用程序,由纽约大学(NYU)和弗吉尼亚大学(UVA)共同开发。这个客户端软件主要用于模拟和评估数据库...