CF1370C题解

本蒟蒻的第二篇题解,找题归功于教练

题目传送门

这道题目找好了规律很简单:

具体思路:

题目大意:

有一个正整数 nn。两名玩家轮流操作。每次操作可以执行以下一种:

  • nn 除以一个 nn 的奇数因子。
  • nn 减去 11

问先手是否有必胜策略。如果先手有必胜策略,输出 Ashishgup,否则输出 FastestFinger

题目分析:

首先,拿到 11 的会输掉。

直观分析可以得到:

  • AA 拿到 22 或奇数的时候必赢,因为 212-1 或奇数 ÷\div 奇数都使得对方得到 11

在此基础上继续分析其他数值:设 pip_i 为奇质数:

  • 如果一个数是 2×p2\times p,那么 AA 只能执行 ÷\div 奇数操作,对方拿到 22,对方必赢,因此 AA 必输。

  • 如果一个数是 2×p1×p2×...2\times p_1\times p_2\times... 那么 AA 可以执行 ÷\div 奇数操作,是的对方拿到 2×p2\times p,因此 AA 必赢。

  • AA2k,k>12^k,k>1 时候, AA 只能执行 1-1 操作,因此 AA 必输。

  • 如果一个数是是 2k×p1×p2...2^k\times p_1\times p_2...AA 执行 ÷\div 奇数操作,对方得到 2k2^k,对方必输,因此 AA 必赢。

知道以上信息代码就很简单了。

源码:

//A 必胜态 2,3,奇数...   2*ji^2,2^k*ji
//A 必输 1,4,8...2^k(k>1);2*ji 
#include <bits/stdc++.h>
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";
	}
	return 0;
}
posted @   KK_SpongeBob  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
点击右上角即可分享
微信分享提示