uva 141 - The Spot Game

点击打开链接

题目意思:     有两个人在玩游戏,游戏是在长为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;
}
时间: 2024-08-17 12:56:05

uva 141 - The Spot Game的相关文章

uva 141 The Spot Game hash

  很简单的hash,可以知道只需要保存每行每列的总个数即可唯一确定图,所以只需开两个50的数组即可,然后对最长为100的字符串进行hash,一开始想直接ELF,但后来发现还是有重复,懒得写拉链法了,直接用map,0.008s就过了 /* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <iostre

UVa 141:The Spot Game

题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=77 类型: 哈希判重 + 模拟 原题: The game of Spot is played on an NxN board as shown below for N = 4. During the game, alternate players may either place

UVa 156 Ananagrams:用STL multimap&amp;amp;set处理字典中的重复元素

156 - Ananagrams Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=98&page=show_problem&problem=92 Most crossword puzzle fans are used to anagrams--groups of words with the same letters

UVa 10387 Billiard:计算几何&amp;amp;反射

10387 - Billiard Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=101&page=show_problem&problem=1328 In a billiard table with horizontal side a inches and vertical side b inches, a bal

【UVA 10307 Killing Aliens in Borg Maze】最小生成树, kruscal, bfs

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20846 POJ 3026是同样的题,但是内存要求比较严格,并是没有过... 对以迷宫形式给定的一些点求最小生成树,不过这里的边并不是抽象的两点间笛卡尔距离,也不是折线距离(迷宫中有障碍),而是需要用四个方向的搜索来求. 用bfs求出任两点间的最短距离后,可用kruscal求出最小生成树. 这次值得一提的是对并查集的一点改造:由于每个顶点由一组(x,y)坐标唯一确定

UVa 10602

链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=113&page=show_problem&problem=1543 类型:贪心 原题: Company Macrohard has released it's new version of editor Nottoobad, which can understand a few voice commands.

UVa 10392 Factoring Large Numbers:素因子分解

10392 - Factoring Large Numbers Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=100&page=show_problem&problem=1333 One of the central ideas behind much cryptography is that factoring

UVa 10182 Bee Maja:规律&amp;amp;O(1)算法

10182 - Bee Maja Time limit: 3.000 seconds http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=1123 Maja is a bee. She lives in a bee hive with thousands of other bees. This bee hive c

算法题之UVA 763

Fibinary Numbers The standard interpretation of the binary number 1010 is 8 + 2 = 10. An alternate way to view the sequence ``1010'' is to use Fibonacci numbers as bases instead of powers of two. For this problem, the terms of the Fibonacci sequence