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

思路:题目就是给你一个拓扑图,然后指定点的位置放棋子,然后两人轮流移动棋子(题目中的边的关系),直到一方不能移动。

SG函数裸题,之前接触的两道一个是推的关系,一个是取石子的。这个比较明显的就是出度为0的点,sg值为0。然后深搜得到其他点的sg值,棋子的异或和为0 则P必败,否则N必胜

由于递归写的很不好,导致没过。最开始竟然用队列随便写了一个。(TLE),后来尝试用dfs写了,WA,迫于无奈只好看题解了(果真就是dfs)  后面附有错误代码

AC代码:

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
using namespace std;
#define in freopen("in.txt", "r", stdin);
typedef long long ll;
const int inf = 0x3f3f3f3f; vector<int> G[1010];
int sg[1010];
int n, xi, u, v, m, x;
int dfs(int id) { //为什么感觉不是太难写,自己就是写不出来。 T_T !!!
if(sg[id] != -1) return sg[id];//已经有了直接返回
bool vis[1010];//标记,求mex
memset(vis, false, sizeof(vis));
for(int i = 0; i < G[id].size(); i++) {
sg[G[id][i]] = dfs(G[id][i]);//递归求出后继sg值
vis[sg[G[id][i]]]= true;//标记后继的sg值
}
for(int i = 0; ; i++) {
if(!vis[i]) {
return sg[id] = i;//求自己的sg值
}
}
} int main() {
while(~scanf("%d", &n)) {
memset(G, 0, sizeof(G));
for(int i = 0; i < n; i++) {
scanf("%d", &xi);
while(xi--) {//存图
scanf("%d", &v);
G[i].push_back(v);
}
}
memset(sg, -1, sizeof(sg));
while(scanf("%d", &m) && m) {
int sum = 0;
while(m--) {//异或和
scanf("%d", &x);
sum ^= dfs(x);
}
if(sum)
printf("WIN\n");
else
printf("LOSE\n");
}
}
}

瞎写的队列代码(TLE)

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
using namespace std;
#define in freopen("in.txt", "r", stdin);
typedef long long ll;
const int inf = 0x3f3f3f3f; vector<int> G[1010];
int sg[1010];
int n, xi, u, v, m, x; void SG() {
queue<int> q;
for(int i = 0; i < n; i++) {
if(G[i].size() == 0)
sg[i] = 0;
else q.push(i);//需要求的点i
}
bool vis[1010];
while(!q.empty())
memset(vis, false, sizeof(vis));
int u = q.front();
bool flag = false;
for(int j = 0; j < G[u].size(); j++) {
if(sg[G[u][j]] != -1) {//如果后继有一个不知道的就换
vis[sg[G[u][j]]] = true;
} else {
flag = true;
q.push(u);
q.pop();
}
}
if(flag == false) {//说明这个点的sg值可以求
for(int j = 0; j <= 1010; j++) {
if(vis[j] == false) {
sg[u] = j;
break;
}
}
q.pop();
}
}
} int main() {
while(~scanf("%d", &n)) {
memset(G, 0, sizeof(G));
for(int i = 0; i < n; i++) {
scanf("%d", &xi);
if(xi == 0)
continue;
else {
while(xi--) {
scanf("%d", &v);
G[i].push_back(v);
}
}
}
memset(sg, -1, sizeof(sg));
SG();
while(~scanf("%d", &m) && m) {
int sum = 0;
while(m--) {
scanf("%d", &x);
sum ^= sg[x];
}
if(sum)
printf("WIN\n");
else
printf("LOSE\n");
}
}
}

自己写的错误DFS代码:

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
using namespace std;
#define in freopen("in.txt", "r", stdin);
typedef long long ll;
const int inf = 0x3f3f3f3f; vector<int> G[1010];
int sg[1010], indegree[1010];
int n, xi, u, v, m, x, topu;
vector<int> GB[1010];//该点的 后继值
void SG(int id) {
for(int i = 0; i < G[id].size(); i++) {//我刚开始也写的bool vis[maxn] 但是我以为这个vis的状态会被破坏 T_T
if(sg[G[id][i]] != -1)
GB[id].push_back(sg[G[id][i]]);
else {
SG(G[id][i]);//瞎写我以为这样求下去,sg[G[id][i]]的值就有了 但是我还是感觉就有了。。。。
GB[id].push_back(sg[G[id][i]]);
}
}
sg[id] = *min_element(GB[id].begin(), GB[id].end()) - 1;//直接求sg值
} int main() {
while(~scanf("%d", &n)) {
memset(G, 0, sizeof(G));
memset(GB, 0, sizeof(GB));
memset(indegree, 0, sizeof(indegree));
for(int i = 0; i < n; i++) {
scanf("%d", &xi);
if(xi == 0)
continue;
else {
while(xi--) {
scanf("%d", &v);
G[i].push_back(v);
indegree[v]++;//因为是一个图,我就打算从根节点开始往下搜
}
}
}
memset(sg, -1, sizeof(sg));
for(int i = 0; i < n; i++) {
if(G[i].size() == 0)
sg[i] = 0;
else if(indegree[i] == 0)
topu = i;//根节点
}
SG(topu);
while(~scanf("%d", &m) && m) {
int sum = 0;
while(m--) {
scanf("%d", &x);
sum ^= sg[x];
}
if(sum)
printf("WIN\n");
else
printf("LOSE\n");
}
}
}

HDU1425 A Chess Game的更多相关文章

  1. hdu4405 Aeroplane chess

    Aeroplane chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  2. HDU 5742 Chess SG函数博弈

    Chess Problem Description   Alice and Bob are playing a special chess game on an n × 20 chessboard. ...

  3. POJ2425 A Chess Game[博弈论 SG函数]

    A Chess Game Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 3917   Accepted: 1596 Desc ...

  4. HDU 4832 Chess (DP)

    Chess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  5. 2016暑假多校联合---A Simple Chess

    2016暑假多校联合---A Simple Chess   Problem Description There is a n×m board, a chess want to go to the po ...

  6. HDU5724 Chess(SG定理)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5724 Description Alice and Bob are playing a spe ...

  7. BFS AOJ 0558 Chess

    AOJ 0558 Chess http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0558    在H * W的地图上有N个奶酪工厂,每个 ...

  8. Codeforces Round #379 (Div. 2) D. Anton and Chess 水题

    D. Anton and Chess 题目连接: http://codeforces.com/contest/734/problem/D Description Anton likes to play ...

  9. dp - Codeforces Round #313 (Div. 1) C. Gerald and Giant Chess

    Gerald and Giant Chess Problem's Link: http://codeforces.com/contest/559/problem/C Mean: 一个n*m的网格,让你 ...

随机推荐

  1. ACM学习历程—POJ3565 Ants(最佳匹配KM算法)

    Young naturalist Bill studies ants in school. His ants feed on plant-louses that live on apple trees ...

  2. ACM学习历程—HDU4415 Assassin’s Creed(贪心)

    Problem Description Ezio Auditore is a great master as an assassin. Now he has prowled in the enemie ...

  3. 第K大子集-LH

    题解:搜索+二分 对于每个数有选与不选两种情况.然后我们先搜前一半的状态,每个数选还是不选. 有2^17种,然后我将每种状态拍一个序先存着.然后我再搜后一半的状态,2^18种. 假设后一半某一种情况的 ...

  4. git导入项目

    远程仓库已经存在,使用的是gitblit,作为终端eclipse如何从中拷贝代码呢? 0.准备工作,windows->preference->team->git->config ...

  5. Azure上部署Barracuda WAF集群 --- 1

    公有云上的第一层防护,一般要采用Proxy模式的安全设备. 梭子鱼的WAF是最早支持Azure China公有云的安全设备. 本文记录了在Azure上安装部署Barracuda的过程.下面就是安装部署 ...

  6. 【转】Pro Android学习笔记(十七):用户界面和控制(5):日期和时间控件

    目录(?)[-] DatePicker和TimePicker控件 DigitalClock和AnalogClock控件 DatePicker和TimePicker控件 使用DatePicker和Tim ...

  7. 关于使用C# 启动msi失败的问题

    原以为在启动msi是件小儿科的事,上代码: ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = "C:\\myTest ...

  8. Go语言是如何处理栈的

    转自:http://tonybai.com/2014/11/05/how-stacks-are-handled-in-go/ Go 1.4Beta1刚刚发布,在Go 1.4Beta1中,Go语言的st ...

  9. Ruby代码块(Block)

    1.什么是代码块 在Ruby中,{}或do...end之间的代码是一个代码块.代码块只能出现在一个方法的后边,它紧接在方法最后一个参数的同一行上,由yield关键字调用.例如: [1,2,3,4,5] ...

  10. linux日常管理-xarge_exec

    在find搜索到文件之后再进行操作 exec是find的一个选项. {}表示前面搜索到的结果,\:是exec特殊的用法. xarge拥有同样的功能,需用选项 -i 可以用在其他命令的后面