2013 多校第六场 hdu 4664 Triangulation(SG问题)
2013-08-10 17:01
357 查看
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4664
题目大意:N个平面,每个平面有ni个点,组成凸多边形,两个人玩游戏,划线,他们可以划任意一个平面的两个点,有以下要求:两个人划得线不能交叉,不要划已经划过的线,如果一个平面被划了一个空心的三角形,那么这个平面就不能继续划线了。Carol先来,两个人轮着画,谁没线划了就输了,问你最后谁赢。
思路:SG问题。先考虑一个平面,因为画成三角形,就没得画了,所以谁都不能去画一条公共顶点的线,要不然就是自寻死路,因为对方再画一条,你就输了,所以,所有划得线都是不能有公共顶点的,也就是每画一条线,就把这个平面又分成了两个平面,也就是SG定理中的异或,即sg[ n ] = mex(sg[ i ] ^sg[n - i - 2])。由于ni很大,不能直接来,还需要打表,找循环节。这里打印前100个可以发现,有一个循环节,长度是34,。最后再把所有的平面都异或起来就好了。
这里还有一点需要注意,循环节不要从39开始,100左右差不多,因为中间有一个sg[ 52 ]!=sg[ 86 ]。太坑了,比赛的时候,我们就是从39开始计算的,WA了很多遍,还好最后被队友发现了。。= =
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int sg[] = {0,0,1,1,2,0,3,1,1,0,3,3,2,2,4,0,5,2,2,3,3,0,1,1,3,0,2,1,1,0,4,5,2,7,4,0,1,1,2,
0,3,1,1,0,3,3,2,2,4,4,5,5,2,3,3,0,1,1,3,0,2,1,1,0,4,5,3,7,4,8,1,1,2,
0,3,1,1,0,3,3,2,2,4,4,5,5,9,3,3,0,1,1,3,0,2,1,1,0,4,5,3,7,4,8,1,1,2,
0,3,1,1,0,3,3,2,2,4,4,5,5,9,3,3,0,1,1,3,0,2,1,1,0,4,5,3,7,4,8,1,1,2,
0,3,1,1,0,3,3,2,2,4,4,5,5,9,3,3,0,1,1,3,0,2,1,1,0,4,5,3,7,4,8,1,1,2,
0,3,1,1,0,3,3,2,2,4,4,5,5,9,3,3,0,1,1,3,0,2,1,1,0,4};
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
int ans = 0;
for(int i = 1;i<=n;i++)
{
int a;
scanf("%d",&a);
if(a<100) ans = ans^sg[a];
else ans = ans^sg[(a-100)%34 + 100];
}
if(ans == 0)
puts("Dave");
else puts("Carol");
}
return 0;
}
打表代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 1111;
int sg[MAXN];
int get_sg(int n)
{
if(sg
!=-1) return sg
;
int hash[MAXN] = {0};
for(int i = 0;i<n-1;i++)
{
int j = n - i - 2;
sg[i] = get_sg(i);
sg[j] = get_sg(j);
hash[sg[i]^sg[j]] = 1;
}
for(int i = 0;;i++)
if(hash[i]==0)
return i;
}
int main()
{
//freopen("D://out.txt","w",stdout);
memset(sg,-1,sizeof(sg));
sg[1] = 0;
sg[2] = 1;
for(int i = 1;i<=200;i++)
{
sg[i] = get_sg(i);
printf("%d,",sg[i]);
}
return 0;
}
题目大意:N个平面,每个平面有ni个点,组成凸多边形,两个人玩游戏,划线,他们可以划任意一个平面的两个点,有以下要求:两个人划得线不能交叉,不要划已经划过的线,如果一个平面被划了一个空心的三角形,那么这个平面就不能继续划线了。Carol先来,两个人轮着画,谁没线划了就输了,问你最后谁赢。
思路:SG问题。先考虑一个平面,因为画成三角形,就没得画了,所以谁都不能去画一条公共顶点的线,要不然就是自寻死路,因为对方再画一条,你就输了,所以,所有划得线都是不能有公共顶点的,也就是每画一条线,就把这个平面又分成了两个平面,也就是SG定理中的异或,即sg[ n ] = mex(sg[ i ] ^sg[n - i - 2])。由于ni很大,不能直接来,还需要打表,找循环节。这里打印前100个可以发现,有一个循环节,长度是34,。最后再把所有的平面都异或起来就好了。
这里还有一点需要注意,循环节不要从39开始,100左右差不多,因为中间有一个sg[ 52 ]!=sg[ 86 ]。太坑了,比赛的时候,我们就是从39开始计算的,WA了很多遍,还好最后被队友发现了。。= =
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int sg[] = {0,0,1,1,2,0,3,1,1,0,3,3,2,2,4,0,5,2,2,3,3,0,1,1,3,0,2,1,1,0,4,5,2,7,4,0,1,1,2,
0,3,1,1,0,3,3,2,2,4,4,5,5,2,3,3,0,1,1,3,0,2,1,1,0,4,5,3,7,4,8,1,1,2,
0,3,1,1,0,3,3,2,2,4,4,5,5,9,3,3,0,1,1,3,0,2,1,1,0,4,5,3,7,4,8,1,1,2,
0,3,1,1,0,3,3,2,2,4,4,5,5,9,3,3,0,1,1,3,0,2,1,1,0,4,5,3,7,4,8,1,1,2,
0,3,1,1,0,3,3,2,2,4,4,5,5,9,3,3,0,1,1,3,0,2,1,1,0,4,5,3,7,4,8,1,1,2,
0,3,1,1,0,3,3,2,2,4,4,5,5,9,3,3,0,1,1,3,0,2,1,1,0,4};
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
int ans = 0;
for(int i = 1;i<=n;i++)
{
int a;
scanf("%d",&a);
if(a<100) ans = ans^sg[a];
else ans = ans^sg[(a-100)%34 + 100];
}
if(ans == 0)
puts("Dave");
else puts("Carol");
}
return 0;
}
打表代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 1111;
int sg[MAXN];
int get_sg(int n)
{
if(sg
!=-1) return sg
;
int hash[MAXN] = {0};
for(int i = 0;i<n-1;i++)
{
int j = n - i - 2;
sg[i] = get_sg(i);
sg[j] = get_sg(j);
hash[sg[i]^sg[j]] = 1;
}
for(int i = 0;;i++)
if(hash[i]==0)
return i;
}
int main()
{
//freopen("D://out.txt","w",stdout);
memset(sg,-1,sizeof(sg));
sg[1] = 0;
sg[2] = 1;
for(int i = 1;i<=200;i++)
{
sg[i] = get_sg(i);
printf("%d,",sg[i]);
}
return 0;
}
相关文章推荐
- hdu 4664 Triangulation/杭电多校2013第六场1010, SG定理+找规律
- HDU 4664 Triangulation(2013多校6 1010题,博弈)
- HDU-4664 Triangulation(博弈SG打表+类似凸包性质)
- 2013 多校第六场 hdu 4665 Unshuffle
- 2013 多校第六场 hdu 4658 Integer Partition(五边形数定理,整数划分)
- 2013 多校第六场 hdu 4661 Message Passing(树形DP+拓展欧几里得)
- 2013 多校第六场 hdu 4655 Cut Pieces
- 2013 多校第六场 hdu 4662 MU Puzzle
- 2013 多校联合 I I-number(hdu 4608)
- HDU 4637 Rain on your Fat brother 线段与半圆和线段交 简单题 (2013多校联合)
- HDU 4611 (2013多校联赛1001 数学+模拟)
- hdu 4677 并查集+分块算法 好题 (2013多校联合)
- HDU 4651 2013多校联合第5场 Partition 数论
- HDU-4664 Triangulation 博弈,SG函数找规律
- HDU 4619 Warm up 2(2013多校2 1009 二分匹配)
- hdu 4602 partition 2013多校联合训练第一场
- 2013多校联合2 I Warm up 2(hdu 4619)
- 2013 多校联合 2 A Balls Rearrangement (hdu 4611)
- sg函数+nim博弈+打表_______A Simple Nim(hdu 5795 2016多校第六场)
- HDU 4923 Room and Moor (多校第六场C题) 单调栈