题目: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. mongodb与mysql的命令对比

    mongodb与mysql命令对比 传统的关系数据库一般由数据库(database).表(table).记录(record)三个层次概念组成,MongoDB是由数据库(database).集合(col ...

  2. [BZOJ1396&2865]识别子串

    bzoj1396 bzoj2865 dbzoj1396 dbzoj2865 题面 XX在进行字符串研究的时候,遇到了一个十分棘手的问题. 在这个问题中,给定一个字符串\(S\),与一个整数\(K\), ...

  3. ACM学习历程—HDU 5459 Jesus Is Here(递推)(2015沈阳网赛1010题)

    Sample Input 9 5 6 7 8 113 1205 199312 199401 201314 Sample Output Case #1: 5 Case #2: 16 Case #3: 8 ...

  4. 排成一行的li之间的间隙问题

    现象 对于ul下li排成一行的布局(即li的display由list-item设为inline-block): 情况1 如果这些li在书写的时候有换行或者有空格,且ul本身的font-size不为0, ...

  5. HDU1257(简单DP)

    最少拦截系统 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  6. hibernate 数据关联一对多

    一对多,多对一 (在多的一端存放一的外键) 但是在实体类中不需要创建这个外键 // 在一的一方创建Set集合 public class User { private Integer id; priva ...

  7. http请求中的get和post的区别

    1.标准答案 GET在浏览器回退时是无害的,而POST会再次提交请求. GET产生的URL地址可以被Bookmark,而POST不可以. GET请求会被浏览器主动cache,而POST不会,除非手动设 ...

  8. 【java并发编程艺术学习】(二)第一章 java并发编程的挑战

    章节介绍 主要介绍并发编程时间中可能遇到的问题,以及如何解决. 主要问题 1.上下文切换问题 时间片是cpu分配给每个线程的时间,时间片非常短. cpu通过时间片分配算法来循环执行任务,当前任务执行一 ...

  9. source in sight 删除工程

    用十六进制编辑器打开  "我的文档/Source Insight/Projects/PROJECTS.DB3" 文件 ,找到你要删除的项目路径及名称字符串,用0替换相关位置的数据.

  10. AJAX经常遇到的那些问题

    本文主要介绍了AJAX工作原理以及在面试题经常会遇到的问题,目录如下: 什么是Ajax 为什么要使用Ajax? Ajax特点? AJAX优缺点? Ajax流程? XMLhttprequest对象 AJ ...