题目: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. 机器学习:YOLO for Object Detection (一)

    最近看了基于CNN的目标检测另外两篇文章,YOLO v1 和 YOLO v2,与之前的 R-CNN, Fast R-CNN 和 Faster R-CNN 不同,YOLO 将目标检测这个问题重新回到了基 ...

  2. 时空上下文视觉跟踪(STC)算法

    论文原文以及Matlab代码下载 算法概述 而STC跟踪算法基于贝叶斯框架,根据跟踪目标与周围区域形成的的时空关系,在图像低阶特征上(如图像灰度和位置)对目标与附近区域进行了统计关系建模.通过计算置信 ...

  3. Python:更改字典的key

    思路:先删除原键值对,保存值,然后以新键插入字典 格式:dict[newkey] = dict.pop(key) d = {'a':1, 'aa':11} d['b'] = d.pop('a') d[ ...

  4. 多校联合训练&hdu5791 Two

    hdu5791 dp[i][j]表示的是序列A前i个数字和序列B前j个数字的公共子序列的总个数,那么的dp公式就可以这么表示 理解一下此公式若最尾部的a[i]和b[j]相等的话,那么单独的a[i]和b ...

  5. Python错误处理和调试

    错误处理(try...except...finally...) try: print('try...') r = 10 / 0 print('result:', r) except ZeroDivis ...

  6. PHP二维数组,根据多个字段来排序

    如果是最最常见的二维数组排序, 大多数情况下也只用到二维: 用php内置函数 array_multisort( )  是最简单的: <?php 假设, $arr 是一个二维数组, $arg1是取 ...

  7. shell入门-awk-1

    awk对于sed grep的优势在于分段,把分隔符分割成一小段一小段,针对段进行匹配,替换,操作,逻辑判断,比较...等 awk的基本操作 [root@wangshaojun ~]# awk -F ' ...

  8. shell入门-grep2

    案例介绍 搜索关键词带‘root’的行 并输出行号 [root@wangshaojun ~]# cg -n 'root' 1.txt1:root:x:0:0:root:/root:/bin/bash1 ...

  9. javaIO 流分析总结

    Java中的流,可以从不同的角度进行分类. 按照数据流的方向不同可以分为:输入流和输出流. 按照处理数据单位不同可以分为:字节流和字符流. 按照实现功能不同可以分为:节点流和处理流. 输出流: 输入流 ...

  10. fabric差异化部署mysql和lnmp

    1.代码如下: vim lnmp.py ------------------------------------------> #!/usr/bin/env python from fabric ...