2013 ACM/ICPC 南京网络赛F题
题意:给出一个4×4的点阵,连接相邻点可以构成一个九宫格,每个小格边长为1。从没有边的点阵开始,两人轮流向点阵中加边,如果加入的边构成了新的边长为1的小正方形,则加边的人得分。构成几个得几分,最终完成九宫格时,谁的分高谁赢。现在给出两人前若干步的操作,问接下来两人都采取最优策略的情况下,谁赢。
分析:博弈搜索,有人说要加记忆化,我没有加也过了……与赤裸裸的博弈搜索的区别在于对于最终状态,并不是谁无路可走谁输,而是谁分低谁输。注意判断分数相等的情况。在搜索中每个节点要么是必胜态,要么是必败态,可参见这里对NP问题的描述:http://www.cnblogs.com/rainydays/archive/2011/05/27/2059781.html
边的存储与判断不好处理,我是使用了edge_row[ ][ ]数组来存储横向边,edge_col[ ][ ]来存储纵向边。并用其左边(横向)或上边(纵向)的点来代表这条边。
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std; struct Point
{
int x, y;
Point()
{}
Point(int x, int y):x(x), y(y)
{}
}; bool edge_row[][];
bool edge_col[][];
bool tom_turn;
int edge_num;
int tom_score, jerry_score; Point get_point(int a)
{
return Point((a - ) / , (a - ) % );
} void add_edge(Point a, Point b, bool value)
{
if (a.x > b.x || a.y > b.y)
swap(a, b);
if (a.x == b.x)
edge_row[a.x][a.y] = value;
else
edge_col[a.x][a.y] = value;
} int square(Point a)
{
if (a.x < || a.y < || a.x > || a.y > )
return ;
bool ret = true;
ret = ret && edge_row[a.x][a.y];
ret = ret && edge_col[a.x][a.y];
ret = ret && edge_row[a.x + ][a.y];
ret = ret && edge_col[a.x][a.y + ];
if (ret)
return ;
return ;
} int get_score(Point a, Point b)
{
if (a.x > b.x || a.y > b.y)
swap(a, b);
if (a.x == b.x)
return square(Point(a.x - , a.y)) + square(a);
return square(Point(a.x, a.y - )) + square(a);
} void input()
{
tom_turn = true;
tom_score = jerry_score = ;
scanf("%d", &edge_num);
memset(edge_row, , sizeof(edge_row));
memset(edge_col, , sizeof(edge_col));
for (int i = ; i < edge_num; i++)
{
int a, b;
scanf("%d%d", &a, &b);
Point p1 = get_point(a);
Point p2 = get_point(b);
add_edge(p1, p2, true);
if (tom_turn)
tom_score += get_score(p1, p2);
else
jerry_score += get_score(p1, p2);
tom_turn = !tom_turn;
}
} bool dfs(int next_score, int previous_score, bool tom_turn)
{
bool win = false;
bool did = false;
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
if (!edge_row[i][j])
{
did = true;
Point a = Point(i, j);
Point b = Point(i, j + );
add_edge(a, b, true);
int score = get_score(a, b);
win = !dfs(previous_score, next_score + score, !tom_turn);
add_edge(a, b, false);
if (win)
return true;
}
if (!edge_col[j][i])
{
did = true;
Point a = Point(j, i);
Point b = Point(j + , i);
add_edge(a, b, true);
int score = get_score(a, b);
win = !dfs(previous_score, next_score + score, !tom_turn);
add_edge(a, b, false);
if (win)
return true;
}
}
}
if (!did)
{
if (next_score == previous_score)
return !tom_turn;
return next_score > previous_score;
}
return false;
} int main()
{
int case_num;
scanf("%d", &case_num);
for (int i = ; i <= case_num; i++)
{
input();
bool tom_win;
if (tom_turn)
tom_win = dfs(tom_score, jerry_score, tom_turn);
else
tom_win = !dfs(jerry_score, tom_score, !tom_turn);
printf("Case #%d: ", i);
if (tom_win)
printf("Tom200\n");
else
printf("Jerry404\n");
}
return ;
}
2013 ACM/ICPC 南京网络赛F题的更多相关文章
- 2013 ACM/ICPC 长春网络赛F题
题意:两个人轮流说数字,第一个人可以说区间[1~k]中的一个,之后每次每人都可以说一个比前一个人所说数字大一点的数字,相邻两次数字只差在区间[1~k].谁先>=N,谁输.问最后是第一个人赢还是第 ...
- 2013 ACM/ICPC 长沙网络赛J题
题意:一个数列,给出这个数列中的某些位置的数,给出所有相邻的三个数字的和,数列头和尾处给出相邻两个数字的和.有若干次询问,每次问某一位置的数字的最大值. 分析:设数列为a1-an.首先通过相邻三个数字 ...
- 2013 ACM/ICPC 长春网络赛E题
题意:给出一个字符串,要从头.尾和中间找出三个完全相等的子串,这些串覆盖的区间互相不能有重叠部分.头.尾的串即为整个字符串的前缀和后缀.问这个相同的子串的最大长度是多少. 分析:利用KMP算法中的ne ...
- 2013 ACM/ICPC 杭州网络赛C题
题意:驴和老虎,在一个矩阵的两个格子里,有各自的起始方向.两者以相同的速度向前移动,前方不能走时驴总是向右,老虎总是向左.他们不能超出矩阵边界也不能走自己走过的格子(但可以走对方走过的格子).如果不能 ...
- 2019 ICPC南京网络赛 F题 Greedy Sequence(贪心+递推)
计蒜客题目链接:https://nanti.jisuanke.com/t/41303 题目:给你一个序列a,你可以从其中选取元素,构建n个串,每个串的长度为n,构造的si串要满足以下条件, 1. si ...
- HDU 4734 F(x) 2013 ACM/ICPC 成都网络赛
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4734 数位DP. 用dp[i][j][k] 表示第i位用j时f(x)=k的时候的个数,然后需要预处理下小 ...
- 2013 ACM/ICPC 成都网络赛解题报告
第三题:HDU 4730 We Love MOE Girls 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4730 水题~~~ #include < ...
- HDU 4731 Minimum palindrome 2013 ACM/ICPC 成都网络赛
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4731 题解:规律题,我们可以发现当m大于等于3时,abcabcabc……这个串的回文为1,并且字典数最小 ...
- hdu 4762 && 2013 ACM/ICPC 长春网络赛解题报告
这次的答案是猜出来的,如果做得话应该是应该是一个几何概型的数学题: 答案就是:n/(m^(n-1)); 具体的证明过程: 1.首先枚举这M个点中的的两个端点,概率是:n*(n-1); 2.假设这个蛋糕 ...
随机推荐
- 石子合并 区间DP (经典)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1021 设sum[i][j]为从第i为开始,长度为j的区间的值得和.dp[ ...
- GPUImage学习
1.GLProgram--加载vertex和fragment的shader. 好处是完全将shader模块的加载过程独立出来. 学习:每个函数处理一件事,且函数的粒度刚好 在glLinkProgram ...
- 【bzoj1037】 ZJOI2008—生日聚会Party
http://www.lydsy.com/JudgeOnline/problem.php?id=1037 (题目链接) 题意 有n个boy和m个girl排成一排,求使得任意一段的boy个数girl个数 ...
- jquery无限级下拉框
非原创,已修改成通用版,效果如下: 下载:http://files.cnblogs.com/files/EasonJim/jquery.menu.rar 项目相关地址 源码:https://githu ...
- USACO 3.2 ratios 高斯消元
题目原意很简单,就是解一个三元一次方程组 直接高斯消元解方程组,枚举最后一列的倍数(k) 注意double的精度,有很多细节需要处理 /* PROB:ratios LANG:C++ */ #inclu ...
- JavaScript事件
关于JavaScript事件讲解得很全面的一篇文章:http://www.cnblogs.com/tugenhua0707/p/4501843.html 如下代码需要注意的一点是,除了getEvent ...
- 修改php执行用户,并使其拥有root权限
useradd apachephp vi /etc/httpd/conf/httpd.conf 将组和用户修改成apachephp,重启apache,然后用lsof -i:80查看apache的执行用 ...
- Bootstrap新手学习笔记——css
Css模块: 1.网格系统: class前缀:.col-xs-*,.col-sm-*,.col-md-*,.col-lg-* <div class="container"&g ...
- Enterprise Library系列文章目录(转载)
1. Microsoft Enterprise Library 5.0 系列(一) Caching Application Block (初级) 2. Microsoft Enterprise Lib ...
- 微信二维码占座 书本水杯板砖都out了
还在用书本.水杯.坐垫.板砖.铁链占座?你OUT了.新学期开学,重大图书馆开通了扫二维码占座功能,同学们只需扫一扫贴在桌子上的二维码,就可以占座.不过,占座有时间限制,如果没有在规定的时间内返回,系统 ...