HDU

来源:互联网 发布:网络经济学专业 编辑:程序博客网 时间:2024/06/03 13:07

题目:有n个盒子,每个盒子能装s个石子,已经装了c个石子,每次你可以选择一个盒子,你可以选择往盒子里面放1~c^2个石子,但是不能超过盒子的容量,问先手是否必胜

思路:求出t,t是满足t+t*t<s的最大的数,

如果c>t,则先手必胜,sg值为s-c;

如果c=t,则先手必败;

如果c<t,则问题转换成可以装t个石子,已经装了c个石子的问题,为什么?因为你必须让对方面对c=t这个局面,这是一个先手必败局面

代码:

#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream>#include<algorithm>#include<ctime>#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<list>#include<numeric>using namespace std;#define LL long long#define ULL unsigned long long#define INF 0x3f3f3f3fn#define mm(a,b) memset(a,b,sizeof(a))#define PP puts("*********************");template<class T> T f_abs(T a){ return a > 0 ? a : -a; }template<class T> T gcd(T a, T b){ return b ? gcd(b, a%b) : a; }template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}// 0x3f3f3f3f3f3f3f3f//0x3f3f3f3fint dfs(int s,int c){    int t=(double)sqrt(1.0*s);    while(t+t*t>=s) t--;    if(c>t) return s-c;    if(c==t) return 0;    return dfs(t,c);}int main(){    int cas=0,n,s,c;    while(~scanf("%d",&n)){        if(!n)            break;        int sg=0;        while(n--){            scanf("%d%d",&s,&c);            sg=(sg^dfs(s,c));        }        printf("Case %d:\n",++cas);        if(sg>0) printf("Yes\n");        else printf("No\n");    }    return 0;}


原创粉丝点击