题意:给出一个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题的更多相关文章

  1. 2013 ACM/ICPC 长春网络赛F题

    题意:两个人轮流说数字,第一个人可以说区间[1~k]中的一个,之后每次每人都可以说一个比前一个人所说数字大一点的数字,相邻两次数字只差在区间[1~k].谁先>=N,谁输.问最后是第一个人赢还是第 ...

  2. 2013 ACM/ICPC 长沙网络赛J题

    题意:一个数列,给出这个数列中的某些位置的数,给出所有相邻的三个数字的和,数列头和尾处给出相邻两个数字的和.有若干次询问,每次问某一位置的数字的最大值. 分析:设数列为a1-an.首先通过相邻三个数字 ...

  3. 2013 ACM/ICPC 长春网络赛E题

    题意:给出一个字符串,要从头.尾和中间找出三个完全相等的子串,这些串覆盖的区间互相不能有重叠部分.头.尾的串即为整个字符串的前缀和后缀.问这个相同的子串的最大长度是多少. 分析:利用KMP算法中的ne ...

  4. 2013 ACM/ICPC 杭州网络赛C题

    题意:驴和老虎,在一个矩阵的两个格子里,有各自的起始方向.两者以相同的速度向前移动,前方不能走时驴总是向右,老虎总是向左.他们不能超出矩阵边界也不能走自己走过的格子(但可以走对方走过的格子).如果不能 ...

  5. 2019 ICPC南京网络赛 F题 Greedy Sequence(贪心+递推)

    计蒜客题目链接:https://nanti.jisuanke.com/t/41303 题目:给你一个序列a,你可以从其中选取元素,构建n个串,每个串的长度为n,构造的si串要满足以下条件, 1. si ...

  6. 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的时候的个数,然后需要预处理下小 ...

  7. 2013 ACM/ICPC 成都网络赛解题报告

    第三题:HDU 4730 We Love MOE Girls 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4730 水题~~~ #include < ...

  8. HDU 4731 Minimum palindrome 2013 ACM/ICPC 成都网络赛

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4731 题解:规律题,我们可以发现当m大于等于3时,abcabcabc……这个串的回文为1,并且字典数最小 ...

  9. hdu 4762 && 2013 ACM/ICPC 长春网络赛解题报告

    这次的答案是猜出来的,如果做得话应该是应该是一个几何概型的数学题: 答案就是:n/(m^(n-1)); 具体的证明过程: 1.首先枚举这M个点中的的两个端点,概率是:n*(n-1); 2.假设这个蛋糕 ...

随机推荐

  1. localStorage和sessionStorage的区别

    //在chrome测试的结果; 知识点1:localStorage和sessionStorage的区别; localStorage生命周期是永久,这意味着除非用户显示在浏览器提供的UI上清除local ...

  2. Servlet,GenericServlet和HttpServlet的继承关系

    HttpServlet是GenericServlet的子类. GenericServlet是个抽象类,必须给出子类才能实例化.它给出了设计servlet的一些骨架,定义了servlet生命周期,还有一 ...

  3. shell 命令遇到的一些问题

    1.  command not found 一般都是未安装,需要root 权限去安装服务,就可正常使用.比如rz, sz, crontab, sendemail, lftp等 2. rz 传输失败,输 ...

  4. codevs1003 电话连线

    题目描述 Description 一个国家有n个城市.若干个城市之间有电话线连接,现在要增加m条电话线(电话线当然是双向的了),使得任意两个城市之间都直接或间接经过其他城市有电话线连接,你的程序应该能 ...

  5. 安装最新版本的ReSharper导致原生全局搜索工具的消失问题

    经过检测,是由于启用了一个插件导致的,禁用即可,如下图:

  6. java连接mysql(二)

    模拟转账成功时的业务场景 import java.sql.*; public class TransactionDemo1 { public static void main(String[] arg ...

  7. Asp.Net MVC3 简单入门详解过滤器Filter

    http://www.cnblogs.com/boruipower/archive/2012/11/18/2775924.html 前言 在开发大项目的时候总会有相关的AOP面向切面编程的组件,而MV ...

  8. Spring实战学习笔记之SpEL表达式

            在Spring XML配置文件中装配Bean的属性和构造参数都是静态的,而在运行期才知道装配的值,就可以使用SpEL实现         SpEL表达式的首要目标是通过计算获得某个值. ...

  9. CSS3 动画animation

    关键帧 什么是关键帧.一如上面对Flash原理的描述一样,我们知道动画其实由许多静态画面组成,第一个这样的静态画面可以表述为一帧.其中关键帧是在动画过程中体现了物理明显变化的那些帧. 比如之前的例子中 ...

  10. LUA的编译、环境等

    Lua的环境.编译等 Lua命令行 lua命令行选项: -i:进入交互式 -e:执行lua代码 -l:加载库文件 例如使用下面的命令启动lua解释器,可以重新定义lua提示符. lua -i -e & ...