思路:
设s为容量,c为当前数量,子游戏即仅对于一个箱子分析,若c+cc>=s,则必胜,因为可直接填满箱子。
引入新变量t,且t+tt==s-1,此时t+tt为最接近s且小于s的数,将t与c对比进行分析
c>t:必胜,可作图计算sg值,SG(s,s)=0,SG(s,s-1)=1,SG(s,s-2)=2… 故SG(s,s-c)=s-c,即此时sg值为s-c。
c=t:必败,因t+tt最接近s且小于s,当前局面无法填满箱子取得胜利,而就算c最小增加1,也会使下一局面必胜。此情况sg值为0。
c<t:无法确定,需递归求解,若能使c=t,则下一局面必败,则此时必胜,所以只要c+c*c>=t即可,形同上故可递归计算,getsg(c,t)。
代码:
#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
int getsg(int c,int s)
{
int t=sqrt(double(s));
while(t+t*t>=s)
t--;
if(c>t) return s-c;
if(c==t) return 0;
if(c<t) return getsg(c,t);
}
int main()
{
int n;
int ans=0;
cin>>n;
for(int i=0;i<n;i++)
{
int s,c;
cin>>s>>c;
ans^=getsg(c,s);
}
if(ans==0) cout<<"No"<<endl;
else cout<<"Yes"<<endl;
return 0;
}