Stone Game



 
  

Stone Game

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 3797    Accepted Submission(s): 1230

Problem Description
This game is a two-player game and is played as follows:1. There are n boxes; each box has its size. The box can hold up to s stones if the size is s.2. At the beginning of the game, there are some stones in these boxes.3. The players take turns choosing a box and put a number of stones into the box. The number mustn’t be great than the square of the number of stones before the player adds the stones. For example, the player can add 1 to 9 stones if there are 3 stones in the box. Of course, the total number of stones mustn’t be great than the size of the box.4.Who can’t add stones any more will loss the game.Give an Initial state of the game. You are supposed to find whether the first player will win the game if both of the players make the best strategy.
 

Input
The input file contains several test cases.Each test case begins with an integer N, 0 < N ≤ 50, the number of the boxes.In the next N line there are two integer si, ci (0 ≤ ci ≤ si ≤ 1,000,000) on each line, as the size of the box is si and there are ci stones in the box.N = 0 indicates the end of input and should not be processed.
 

Output
For each test case, output the number of the case on the first line, then output “Yes” (without quotes) on the next line if the first player can win the game, otherwise output “No”.
 

Sample Input
 
    
32 03 36 226 36 30
 

Sample Output
 
    
Case 1:YesCase 2:
No

一道SG形的题目,但是要比一般的SG要复杂

题意:

    有n个容量为s的盒子,每个盒子里原有的石子有ci个,问谁能赢

思路:

    每个盒子中的s 和c 之间存在的输赢关系是一定的,把每个盒子的SG值先异或可以得最终这个游戏得SG值,根据SG来判断输赢

    比如:一个盒子得s = 20

如果 c=20, 那么先手必败 SG[20] = 0;

如果c= 19 SG【19】得后继为SG【20】,即SG【19 】 = 1

如果c = 18 SG【18】得后继为SG【19】,SG【20】,即SG【18】 = 2

.......

如果c = 4 SG【4】得后继有。。。,SG【4】得后继为SG【4】= 16

当c = 3是c不能经过一步操作到达20,所以他的后继中无SG【20】,所以最小值为0,所以SG【3】 = 0;

同理 SG【2】 = 1;

SG【1】 = 0;

SG【0】 = 0;

//SG【】得后继就是这个数能一步到达得数

从4后可以看成一个循环,3和20都是必输点,而后面的0也是必输点

当一个人处在必胜点的时候,他可以通过操作来是到达离他最近的一个必输点,那么他就是必胜得,同理,当一个人先手处于必输点得时候,那么他就是必输的

#include<iostream>
#include<math.h>
using namespace std;
int getsg(int s, int c) {
    int t = sqrt(s);
    while (t * t + t >= s) t --;
    if (c > t) return s - c;
    else return getsg(t, c);
}
int main() {
    int n;
    int cnt = 0;
    while(cin >> n && n) {
        cnt ++;
        int t = 0;
        while(n--) {
            int s, c;
            cin >> s >> c;
            t ^= getsg(s, c);
        }
        cout << "Case "<<cnt<< ":"<< endl;
        if (t) {
            cout << "Yes"<<endl;
        }else{
            cout << "No"<<endl;
        }
    }
    return 0;
}

   

猜你喜欢

转载自blog.csdn.net/henu_jizhideqingwa/article/details/81011913