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的网格,让你 ...
随机推荐
- 6_State 游戏开发中使用状态机
### State 不好的代码 ``` //处理玩家输入的代码 void Heroine::handleInput(Input input) { if (input == PRESS_B) { if ...
- [SPOJ-DISUBSTR]Distinct Substrings
vjudge 题意 给你一个串,求不同字串个数. \(n\le10^5\) sol 直接建SAM然后输出\(\sum_{i=1}^{tot}len[i]-len[fa[i]]\) code #incl ...
- CQOI2018做题记录
T1.破解D-H协议 传送门 这个题就是BSGS的板子题-- 然后这里补充一点嘛,就是第二重循环的枚举范围.我们是在枚举\(a^{tm-y}\),把tm换成i,这个的最大值就是\(i - (m - 1 ...
- 洛谷【P1138】第k小整数
题目传送门:https://www.luogu.org/problemnew/show/P1138 桶排: 对于值域在可以接受的范围内时,我们可以用不依赖比较的桶排去将数据排序.因为桶排不依赖比较排序 ...
- CentOS6 下Samba服务器的安装与配置
原地址:http://www.cnblogs.com/mchina/archive/2012/12/18/2816717.html 一.简介 Samba是一个能让Linux系统应用Microsoft网 ...
- Linux keepalived与lvs的深入分析
一)概述 在本篇文章里,我们会涉及两部份内容,一个是LVS,另一个则是keepalived. 即我们用LVS和keepalived实现了负载均衡及高可用的服务器. LVS有实现三种IP负载均衡技术 ...
- nginx与apache 限制ip连接数和带宽方法
今天有个人问我,nginx怎么限制ip连接数,突然想不起来了,年龄大了,脑子不怎么好使了.还要看一下配置才想起了.那个人又问我,你测试过的吗?一下子把我问蒙了,我真没测试过了,也不知道启作用了没有. ...
- Ruby代码块(Block)
1.什么是代码块 在Ruby中,{}或do...end之间的代码是一个代码块.代码块只能出现在一个方法的后边,它紧接在方法最后一个参数的同一行上,由yield关键字调用.例如: [1,2,3,4,5] ...
- Android精品源码分享第四波袭来,免费下载!
今天又汇总了几个优质的源码分享出来给大家!希望可以帮到需要的朋友~1.Android实现-带动画的饼图控件 分享的是Android技术相关的源码内容,希望对大家的Android学习有帮助.带动画的饼图 ...
- net.sf.json-lib maven依赖问题.
<dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</art ...