说好的这个星期要搞数学和几何……
两题都很简单,暴力求出SG值即可
还有注意一下xor时要打括号,不然各种意外错误%>_<%
BZOJ 1188
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 30;
const int MAXP = 10001;
int t,n;
int Sg[MAXN];
int data[MAXN];
int SG(int x)
{
if (x == n) return 0;
if (Sg[x] != -1) return Sg[x];
bool vis[MAXP];
memset(vis,false,sizeof(vis));
for (int i=x+1;i<=n;i++)
for (int j=i;j<=n;j++) vis[SG(i)^SG(j)] = true;
for (int i=0;;i++) if (!vis[i]) return Sg[x] = i;
}
int main()
{
scanf("%d",&t);
while (t--)
{
memset(Sg,-1,sizeof(Sg));
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&data[i]);
int ans =0, cnt = 0;
for (int i=1;i<=n;i++) if (data[i]&1) ans ^= SG(i);
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)
for (int k=j;k<=n;k++)
if ((ans^SG(i)^SG(j)^SG(k)) == 0)
{
cnt++;
if (cnt == 1) printf("%d %d %d\n",i-1,j-1,k-1);
}
if (!cnt) printf("-1 -1 -1\n");
printf("%d\n",cnt);
}
return 0;
}
BZOJ 1874
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1001;
const int MAXA = 1001;
int n,m;
int data[MAXN],can[MAXA];
int SG[MAXA];
inline int GetSG(int x)
{
if (x <= 0) return SG[0] = 0;
if (SG[x] != -1) return SG[x];
bool vis[MAXA];
memset(vis,false,sizeof(vis));
for (int i=1;i<=m && x >= can[i];i++) vis[GetSG(x-can[i])] = true;
for (int i=0;;i++) if (!vis[i]) return SG[x] = i;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&data[i]);
scanf("%d",&m);
for (int i=1;i<=m;i++) scanf("%d",&can[i]);
memset(SG,-1,sizeof(SG));
int ans = 0,cnt = 0, first;
for (int i=1;i<=n;i++) ans ^= GetSG(data[i]);
if (ans == 0) printf("NO\n");
else
for (int i=1;i<=n;i++)
{
int temp = ans^GetSG(data[i]);
for (int j=1;j<=m && data[i] >= can[j];j++) if ((GetSG(data[i]-can[j])^temp) == 0)
{
printf("YES\n%d %d\n",i,can[j]);
return 0;
}
}
return 0;
}