HDU1425 A Chess Game
题目: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的更多相关文章
- hdu4405 Aeroplane chess
Aeroplane chess Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- HDU 5742 Chess SG函数博弈
Chess Problem Description Alice and Bob are playing a special chess game on an n × 20 chessboard. ...
- POJ2425 A Chess Game[博弈论 SG函数]
A Chess Game Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 3917 Accepted: 1596 Desc ...
- HDU 4832 Chess (DP)
Chess Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- 2016暑假多校联合---A Simple Chess
2016暑假多校联合---A Simple Chess Problem Description There is a n×m board, a chess want to go to the po ...
- HDU5724 Chess(SG定理)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5724 Description Alice and Bob are playing a spe ...
- BFS AOJ 0558 Chess
AOJ 0558 Chess http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0558 在H * W的地图上有N个奶酪工厂,每个 ...
- 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 ...
- 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的网格,让你 ...
随机推荐
- python 标准库 —— 线程与同步(threading、multiprocessing)
1. 创建线程 使用 os 下的 fork() 函数调用(仅限 Unix 系统) import os print('current process (%s) starts ...' % (os.get ...
- do-while-zero 结构在宏定义中的应用
do while 语句在使用宏定义时是一个有用的技巧,说明如下: 假设有这样一个宏定义 #define macro(condition) / if(condition) dosomething() 现 ...
- JEECG datagrid 列表检索条件 添加下拉级联功能
$("#communityId").change( function(){ var id = $(this).children('option:selected').val(); ...
- POJ1112 Team Them Up!
Team them up! Input file teams.in Output file teams.out Your task is to divide a number of persons i ...
- windows下python使用虚拟环境
官方文档: http://pythonguidecn.readthedocs.io/zh/latest/dev/virtualenvs.html virtualenv 是一个创建隔绝的Python环境 ...
- nginx uwsgi wsgi django 这些东西究竟是什么关系
有太多的文章告诉我们nginx uwsgi django 这些东西怎么用了,太多的人知道这些东西的怎么使用,怎么配置,怎么优化,但是还是有一部分人比如我这种水货不知道这些东西到底是啥,为啥一个项目的发 ...
- 用Raspberry Pi搭建Azure IOT解决方案
Raspberry Pi是一款基于Linux的单板机电脑.它由英国的树莓派基金会所开发,目的是以低价硬件及自由软件刺激在学校的基本计算机科学教育.树莓派配备一枚博通(Broadcom)出产的ARM架构 ...
- netty中的引导Bootstrap服务端
引导一个应用程序是指对它进行配置,并使它运行起来的过程. 一.Bootstrap 类 引导类的层次结构包括一个抽象的父类和两个具体的引导子类,如图 8-1 所示 服务器致力于使用一个父 Channel ...
- oracle--存储过程2--bk
oracle存储过程demo1---无返回值的存储过程: /* 写一个过程,可以向book表添加书 */ create table book( id number(4), book_name varc ...
- 问题:request.Headers;结果:HttpWebRequest.Headers 属性
指定构成 HTTP 标头的名称/值对的集合. Headers 集合包含与请求关联的协议标头.下表列出了由系统或由属性或方法设置但未存储在 Headers 中的 HTTP 标头. 标头 设置方 Ac ...