【百题留念】hdoj 1524 A Chess Game(dfs + SG函数应用)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1524

 1 #include<stdio.h>
 2 #include<cstring>
 3 using namespace std;
 4 const int M = 10000000;//
 5 const int N = 1005;
 6 int sg[N], head[N];
 7 int cnt;
 8
 9 struct node{
10     int from;
11     int to;
12     int next;
13 }edge[M];
14
15 void addedge( int from, int to){
16     edge[cnt].from = from;
17     edge[cnt].to = to;
18     edge[cnt].next = head[from];//同一个父节点引出的边
19     head[from] = cnt++;
20 }
21
22 void init(){
23     cnt = 0;//总边数
24     memset(head,-1,sizeof(head));
25     memset(sg,-1,sizeof(sg));
26 }
27
28 int mex(int n){
29     bool g[N];
30     memset(g,false,sizeof(g));
31     if( sg[n] != -1 )
32         return sg[n];
33     for(int i = head[n];i != -1; i = edge[i].next){
34         if( sg[edge[i].to] == -1 )
35             sg[edge[i].to] = mex(edge[i].to);
36         g[sg[edge[i].to]] = true;
37     }
38     for( int i = 0; i < N; ++i)
39         if(!g[i])
40             return i;
41 }
42
43 int main(){
44     int n, m, tmp;
45     while(~scanf("%d",&n)){
46         init();
47         for(int i = 0; i < n; ++i){
48             scanf("%d",&m);
49             for( int j = 0; j < m; ++j){
50                 scanf("%d",&tmp);
51                 addedge(i,tmp);//建图
52             }
53         }
54         while(~scanf("%d",&m)&&m){
55             int ans = 0;
56             for( int i = 0; i < m; ++i){
57                 scanf("%d",&tmp);
58                 ans = ans ^ mex(tmp);
59             }
60             puts(ans?"WIN":"LOSE");
61         }
62     }
63     return 0;
64 }

百题留念        

时间: 2024-10-15 20:21:21

【百题留念】hdoj 1524 A Chess Game(dfs + SG函数应用)的相关文章

HDU 1524 - A Chess Game(sg函数 + dfs)

A Chess Game Problem Description Let's design a new chess game. There are N positions to hold M chesses in this game. Multiple chesses can be located in the same position. The positions are constituted as a topological graph, i.e. there are directed

HDU ACM 1524 A Chess Game-&gt;博弈(SG函数)

题意:一个有向无环图上有n个顶点,每一个顶点都可以放一个棋子或不放,有两个人,每次根据这个图只能将任意一颗棋子移动一步,如果到某一步玩家不能移动时,那么这个人就输. 分析: 1.有向无环图的博弈,dfs把所有顶点的SG值都计算出来,然后对每个棋子的SG值进行异或运算,为0就是先手必败,否则就是先手必胜. 2.如果某个人移动后,所有棋子都在出度为0的顶点,那么他必败. SG函数简介: a.对于给定的有向无环图,定义图中每个顶点的Sprague-Grundy函数g如下:g(x) = mex{ g(y

poj 2425 A Chess Game(SG函数)

A Chess Game Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 3551   Accepted: 1440 Description Let's design a new chess game. There are N positions to hold M chesses in this game. Multiple chesses can be located in the same position. The

POJ 2425 A Chess Game 博弈论 sg函数

http://poj.org/problem?id=2425 典型的sg函数,建图搜sg函数预处理之后直接求每次游戏的异或和.仍然是因为看不懂题目卡了好久. 这道题大概有两个坑, 1.是搜索的时候vis数组应该在函数内声明(似乎这是我经常在搜索里犯的错误,为了省一点空间整道题都写错了): 2.是n个点的有向无环图边数上限是n^2(re了好久QAQ). 在漫长的查资料过程之后终于大概搞懂了sg函数的原理,愉快.下一篇大概会写一个小结. 代码 1 #include<cstdio> 2 #inclu

(c语法百题25)从 n 个数中挑选出最大的数

知识点: 数组灵活运用 for循环灵活运用 简单的算法 内容: 从 n 个数中挑选出最大的数 输入说明: 两行 第一行一个数n,表示总的个数 第二行共n个数字,用空格隔开. 输出说明: 一行,最大数 输入样例: 4 1 2 3 4 输出样例 : 4 #include <stdio.h>#define MAX 200; int main() { int a[MAX],n,i,t; scanf("%d",&n); for (i=0;i<n;i++) { scanf

(c语法百题21)四位整数

知识点: for语句,if语句灵活运用 内容: 编程找出四位整数 abcd 中满足下述关系的数: ( ab + cd )( ab + cd ) = abcd 输入说明: 没有输入 输出说明: 输出abcd,从小到大,一行一个. 1 #include <stdio.h> 2 int main() 3 { 4 int i,a,b; 5 for(i=1000;i<10000;i++) 6 { 7 a=i/100; 8 b=i%100; 9 if((a+b)*(a+b)==i) 10 { 11

(c语法百题12)优惠购物

知识点: if……else 的用法 内容: 节日期间,某超市举行优惠购物活动,规定:所购物品不超过1000元(含)时,按9.5折付款,如超过1000元,则超过部分按9折收费 输入说明: 一行 ,一个数,购物总额 输出说明: 一行 需付购物款(保留两位小数) 输入样例: 1200.58 输出样例 : 1130.52 1 #include <stdio.h> 2 int main() 3 { 4 float a,s; 5 scanf("%f",&a); 6 if (a&

(c语法百题11)输入一个数 ,输出其绝对值

知识点: if语句 内容: 输入一个数 ,输出其绝对值. 输入说明: 一行一个整数 输出说明: 一行一个整数 输入样例: -3 输出样例 : 3 #include <stdio.h> int main() { int a; scanf("%d",&a); if (a<0) { a=-a; } printf("%d\n",a); return 0; } (c语法百题11)输入一个数 ,输出其绝对值,布布扣,bubuko.com

(c语法百题13)符号函数

知识点: if……else……if……else的用法. 内容: 计算下列函数(符号函数): 1 (x>0) y= 0 (x=0) -1 (x<0) 输入说明: 一个整数 输出说明: 一个数字(1,0,或者-1) 输入样例: 12 输出样例: 1 1 #include <stdio.h> 2 int main() 3 { 4 int a; 5 scanf("%d",&a); 6 if (a>0) 7 { 8 printf("1\n"