“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛 I
Posted 樱花落舞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛 I相关的知识,希望对你有一定的参考价值。
有一天,空和白很无聊,决定玩盛大游戏,考虑到两个人玩,他们随便掏了一个游戏出来:在一个n?m 的棋盘上,首先把史蒂芬妮·多拉放在左上角(1,1) 的位置。每次一个人可以将她往下,往右,往右下丢一格。当前回合,谁不能丢史蒂芬妮,谁就输了。(注意,不可以把活人丢出棋盘啦!)游戏总是空先手。
白说,这是一个垃圾游戏!我们每次把史蒂芬妮丢素数个位置吧!(换句话说,每次丢2 或3 或5 或7 或…格)空答应了。
我们都知道,空和白都很聪明,不管哪方存在一个可以必胜的最优策略,都会按照最优策略保证胜利。
玩了一局,空已经知道了这个游戏的套路,现在他决定考考你,对于给定的n 和m ,空是赢是输?如果空必胜,输出“Sora”(无引号);反之,输出“Shiro”(无引号)。
第一行有一个T表示数组组数,1<=T<100000
从第二行开始,每行为棋盘大小,n
、m
分别表示行列。
1=<n<=500
,1=<m<=500
对于每组数据,按题目要求输出。
4 1 1 2 2 10 10 30 30
Shiro Shiro Shiro Sora
解法:
1 可以肯定,如果经过操作这个人可以到右下角,那一定是胜利的
2 n,m很小,我们把所有的情况dfs一次,也就是说对于每种棋盘都有一个记录位置(这里是谁走的)
3 每次dfs都用到上一次的棋盘记录,所以用dp记录下来(比如处理完1*1,再处理1*2,自然需要用1*1的值)
3 代码解释 每次返回都取反 如果上个位置为1,说明这次是0操作,0同理,然后求或,如果这次是1,那么一定有机会让这个位置最后保留为1,为0的情况只有0访问过
1 #include <algorithm> 2 #include <iostream> 3 #include <string.h> 4 #include <cstdio> 5 #include <cmath> 6 #define N 550 7 #define LL long long 8 using namespace std; 9 int dp[N][N]; 10 int n,m; 11 int Solve(int x){ 12 for(int i=2;i*i<=x;i++){ 13 if(x%i==0){ 14 return 0; 15 } 16 } 17 return 1; 18 } 19 int flag[N][N]; 20 vector<int>Ve; 21 int dfs(int x,int y){ 22 if(flag[x][y]) return dp[x][y]; 23 flag[x][y]=1; 24 for(int i=0;i<Ve.size();i++){ 25 if(x-Ve[i]>0) dp[x][y]|=(!dfs(x-Ve[i],y)); 26 if(y-Ve[i]>0) dp[x][y]|=(!dfs(x,y-Ve[i])); 27 if(x-Ve[i]>0&&y-Ve[i]>0) dp[x][y]|=(!dfs(x-Ve[i],y-Ve[i])); 28 } 29 return dp[x][y]; 30 } 31 int main(){ 32 for(int i=2;i<=510;i++){ 33 if(Solve(i)){ 34 Ve.push_back(i); 35 } 36 } 37 for(int i=1;i<=510;i++){ 38 for(int j=i;j<=510;j++){ 39 dfs(i,j); 40 } 41 } 42 int t; 43 scanf("%d",&t); 44 while(t--){ 45 int n,m; 46 scanf("%d%d",&n,&m); 47 if(dp[n][m]==0){ 48 printf("Shiro\n"); 49 }else{ 50 printf("Sora\n"); 51 } 52 } 53 return 0; 54 }
以上是关于“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛 I的主要内容,如果未能解决你的问题,请参考以下文章
“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛 A
“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛 B
“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛 H
“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛 F