CF1370C Number Game——博弈论

题目大意:
有一个正整数 n。两名玩家轮流操作。每次操作可以执行以下一种:
将 n 除以一个 n的奇数因子。
将 n 减去 11。
问先手是否有必胜策略。如果先手有必胜策略,输出 Ashishgup,否则输出 FastestFinger。
题目分析:
原则:拿到1的会输掉。

直观分析可以得到:

  • 1.当A拿到2或奇数的时候必赢,因为2-1或奇数/奇数都使得对方得到1.
    在此基础上继续分析其他数值: 设 p p p为奇质数
    • 1-1. 如果一个数是 2 ∗ p 2*p 2p,那么A只能执行/奇数操作,对方拿到2,对方必赢,因此A必输。
    • 1-2. 如果一个数是 2 ∗ p 1 ∗ p 2 ∗ . . . 2*p_1*p_2*... 2p1p2...那么A可以执行/奇数操作,是的对方拿到 2 ∗ p 2*p 2p,因此A必赢。
  • 2.当A为 2 k , k > 1 2^k,k>1 2k,k>1时候,A只能执行-1操作,因此A必输。
    • 2-1.如果 一个数是是 2 k ∗ p 1 ∗ p 2 . . . 2^k*p_1*p_2... 2kp1p2...,A执行/奇数操作,对方得到 2 k 2^k 2k,对方必输,因此A必赢。
      CF1370C Number Game——博弈论_第1张图片
      参考代码:
//A 必胜态 2,3,奇数...   2*ji^2,2^k*ji
//A 必输 1,4,8。。。2^k(k>1);2*ji 
#include 
using namespace std;
bool Prime(int x) {
	for(int i = 2; i * i <= x; i++) {
		if(x % i == 0) 	return false;
	}
	return true;
}
bool work() {
	int x;
	cin >> x;
	if(x == 1)return 0 ;//0必输态 
	else if(x==2||x&1) return 1;//2和奇数必赢态 
	else if(x&2) {//2*奇数 
		x >>= 1;
		if(Prime(x)) return 0;//2*奇质数:必输态
		else return 1;//2*奇数*奇数 必赢态 
	}
	else {
		while(!(x & 1) )x >>= 1;
		if(x == 1) return 0;//2^k,必输态 
		else return 1;//2^k*ji必赢态。 
	}
}

int main() {
	int t;
	cin >> t;
	while(t--) {
		if(work())cout<<"Ashishgup\n";
		else cout<<"FastestFinger\n";
	}
}

你可能感兴趣的:(博弈)