翻硬币
题目:
[HDU3537] Daizhenyang’s Coin
题解:
先放一个特别好的up,有心情再看吧
这道题是约束6,直接结论跑
坑点:后面给的正面朝上的坐标还有重复?
代码:
#include <map>
#include <cstdio>
using namespace std;
bool pd(int x)
{
int cnt=0;
while (x) {if (x&1) cnt++;x>>=1;}
if (cnt%2) return 0;else return 1;
}
int find(int x)
{
if (pd(x)) return x+1;
else return x;
}
int main()
{
int n,a;
while (~scanf("%d",&n))
{
map<int,bool>mp;int ans=0;
for (int i=1;i<=n;i++)
{
scanf("%d",&a);
if(mp[a]==0)
ans^=find(2*a);
mp[a]=1;
}
if (ans) printf("No\n");else printf("Yes\n");
}
}
删边游戏
它指的是给出一棵树,每次可以在树上删掉一条边,和根节点脱离的部分整个被删掉,最后不能操作的人输。
结论:叶子节点的SG值为0,其它节点的SG值为子树SG值+1 的异或值,最后判断根节点的值
1、题目:
[HDU3094] A tree game
题解:
按照结论做就好了
代码:
#include <cstdio>
#include <cstring>
using namespace std;
const int N=1e5;
int tot,nxt[N*2],point[N],v[N*2],sg[N];
void addline(int x,int y)
{
++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;
++tot; nxt[tot]=point[y]; point[y]=tot; v[tot]=x;
}
void dfs(int x,int fa)
{
int k=0;
for (int i=point[x];i;i=nxt[i])
if (v[i]!=fa)
{
dfs(v[i],x);
k^=sg[v[i]]+1;
}
sg[x]=k;
}
int main()
{
int T,n;
scanf("%d",&T);
while (T--)
{
tot=0;memset(point,0,sizeof(point));
scanf("%d",&n);
for (int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
addline(x,y);
}
dfs(1,0);
if (sg[1]) printf("Alice\n");else printf("Bob\n");
}
}
2、题目:
[POJ3710] Christmas Game
题解:
出现了环,但是环我不会呀,还是先转化成树吧
对于无向图的删边游戏有如下定理性质:
- 对于长度为奇数的环,它的SG值为1;对于长度为偶数的环,它的SG值为0;
- 叶子节点的SG值为0;中间节点的SG值为它的所有子节点的SG值+1后的异或和。
然后这个题就可以做啦,缩点一波然后跑就行了
A了之后觉得这个题的数据真是有毒,不仅重边,有了环的点还有重任
不要忘记给已经不用的点出栈
代码:
#include <cstdio>
#include <cstring>
using namespace std;
const int N=105;
int tot,nxt[1505],point[N],v[1505],stack[N],sg[N],top,vis[N];
void addline(int x,int y)
{
++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;
++tot; nxt[tot]=point[y]; point[y]=tot; v[tot]=x;
}
void clear()
{
tot=top=0;memset(point,0,sizeof(point));
memset(vis,-1,sizeof(vis));memset(sg,0,sizeof(sg));
}
void dfs(int x,int fa)
{
bool fff=0;
vis[x]=1; stack[++top]=x;
for (int i=point[x];i;i=nxt[i])
{
if (v[i]==fa && !fff){fff=1; continue;}
if (vis[v[i]]==1)
{
int now=0,cnt=1;
while (stack[top]!=v[i])
vis[stack[top--]]=0,cnt++;
if (cnt%2) sg[v[i]]=1;
}
else if (vis[v[i]]==-1)
{
dfs(v[i],x);
if (vis[v[i]]) sg[x]^=sg[v[i]]+1;
}
}
if (vis[x]) top--;
}
int main()
{
int n,m,k;
while (~scanf("%d",&n))
{
int kt=0;
for (int i=1;i<=n;i++)
{
clear();
scanf("%d%d",&m,&k);
for (int j=1;j<=k;j++)
{
int x,y;scanf("%d%d",&x,&y);
addline(x,y);
}
dfs(1,0);
kt^=sg[1];
}
if (kt) printf("Sally\n");else printf("Harry\n");
}
}