题目链接:Rake It In

比赛链接:ICPC Asia Nanning 2017

Description

The designers have come up with a new simple game called “Rake It In”. Two players, Alice and Bob, initially select an integer k and initialize a score indicator. An \(4 \times 4\) board is created with 16 values placed on the board. Starting with player Alice, each player in a round selects a \(2 \times 2\) region of the board, adding the sum of values in the region to the score indicator, and then rotating these four values \(90\) degrees counterclockwise.

After \(2k\) rounds in total, each player has made decision in k times. The ultimate goal of Alice is to maximize the final score. However for Bob, his goal is to minimize the final score.

In order to test how good this game is, you are hired to write a program which can play the game. Specifically, given the starting configuration, they would like a program to determine the final score when both players are entirely rational.

Input

The input contains several test cases and the first line provides an integer \(t (1 \le t \le 200)\) which is the number of test cases.

Each case contains five lines. The first line provides the integer \(k (1 \le k \le 3)\). Each of the following four lines contains four integers indicating the values on the board initially. All values are integers between \(1\) to \(10\).

Output

For each case, output an integer in a line which is the predicted final score.

Sample Input

4
1
1 1 2 2
1 1 2 2
3 3 4 4
3 3 4 4
2
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
3
1 1 4 4
4 4 1 1
1 1 4 4
1 4 1 4
3
1 2 3 4
5 1 2 3
4 5 1 2
3 4 5 1

Sample Output

20
40
63
71

Solution

题意

有一块 \(4\times 4\) 的板,Alice 和 Bob 每次选择 \(2\times 2\) 的区域并逆时针旋转 \(90\) 度,这个区域的和累加到总分上。现在 Alice 先手,有 \(k\) 轮游戏,Alice 想要分数最大化,Bob 想要分数最小化,求最终的分数。

题解

DFS 贪心

比较好的解法是对抗搜索 与 \(Alpha-Beta\) 剪枝。

题解给出是上分支定界和启发式搜索。

但是用贪心 + 爆搜竟然过了。

关于对抗搜索和 \(Alpha-Beta\) 剪枝以后再更新。

Code

DFS + 贪心

#include <bits/stdc++.h>
using namespace std;
const int inf = 1000; int k;
int mt[10][10]; // 交换两数
void swap(int &a, int &b) {
a = a ^ b;
b = a ^ b;
a = a ^ b;
} // 逆时针旋转
void rote(int x, int y) {
swap(mt[x][y], mt[x + 1][y]);
swap(mt[x][y + 1], mt[x + 1][y + 1]);
swap(mt[x][y], mt[x + 1][y + 1]);
} // 顺时针旋转
void rerote(int x, int y) {
swap(mt[x][y], mt[x + 1][y + 1]);
swap(mt[x][y + 1], mt[x + 1][y + 1]);
swap(mt[x][y], mt[x + 1][y]);
} // 求和
int sum(int x, int y) {
return mt[x][y] + mt[x + 1][y] + mt[x][y + 1] + mt[x + 1][y + 1];
} int dfs(int step) {
if(step == 2 * k) { // 最后一步
int ans = inf;
for(int i = 0; i < 3; ++i) {
for(int j = 0; j < 3; ++j) {
ans = min(ans, sum(i, j));
}
}
return ans;
} else {
// 奇数步选择最大 偶数步选择最小
int ans = (step & 1)? 0: inf;
for(int i = 0; i < 3; ++i) {
for(int j = 0; j < 3; ++j) {
rote(i, j); // 逆时针旋转
if(step & 1) {
ans = max(ans, sum(i, j) + dfs(step + 1));
} else {
ans = min(ans, sum(i, j) + dfs(step + 1));
}
rerote(i, j); // 回溯时转回来
}
}
return ans;
}
} int main() {
int T;
cin >> T;
while(T--) {
scanf("%d", &k);
for(int i = 0; i < 4; ++i) {
for(int j = 0; j < 4; ++j) {
scanf("%d", &mt[i][j]);
}
}
int ans = dfs(1);
printf("%d\n", ans);
}
return 0;
}

对抗搜索 + \(Alpha-Beta\) 剪枝

#include <bits/stdc++.h>
using namespace std;
const int inf = 1000; int k;
int mt[10][10]; void swap(int &a, int &b) {
a = a ^ b;
b = a ^ b;
a = a ^ b;
} void rote(int x, int y) {
swap(mt[x][y], mt[x + 1][y]);
swap(mt[x][y + 1], mt[x + 1][y + 1]);
swap(mt[x][y], mt[x + 1][y + 1]);
} void rerote(int x, int y) {
swap(mt[x][y], mt[x + 1][y + 1]);
swap(mt[x][y + 1], mt[x + 1][y + 1]);
swap(mt[x][y], mt[x + 1][y]);
} int cnt(int x, int y) {
return mt[x][y] + mt[x + 1][y] + mt[x][y + 1] + mt[x + 1][y + 1];
} int dfs(int sum, int step, int alpha, int beta) {
if(step == 2 * k + 1) {
return sum;
} else {
for(int i = 0; i < 3; ++i) {
for(int j = 0; j < 3; ++j) {
rote(i, j);
if(step & 1) {
alpha = max(alpha, dfs(sum + cnt(i, j), step + 1, alpha, beta));
} else {
beta = min(beta, dfs(sum + cnt(i, j), step + 1, alpha, beta));
}
rerote(i, j);
if(beta <= alpha) break;
}
if(beta <= alpha) break;
}
return (step & 1)? alpha: beta;
}
} int main() {
int T;
cin >> T;
while(T--) {
scanf("%d", &k);
for(int i = 0; i < 4; ++i) {
for(int j = 0; j < 4; ++j) {
scanf("%d", &mt[i][j]);
}
}
int ans = dfs(0, 1, -inf, inf);
printf("%d\n", ans);
}
return 0;
}

ICPC Asia Nanning 2017 I. Rake It In (DFS+贪心 或 对抗搜索+Alpha-Beta剪枝)的更多相关文章

  1. ICPC Asia Nanning 2017 L. Twice Equation (规律 高精度运算)

    题目链接:Twice Equation 比赛链接:ICPC Asia Nanning 2017 Description For given \(L\), find the smallest \(n\) ...

  2. ICPC Asia Nanning 2017 F. The Chosen One (高精度运算)

    题目链接:The Chosen One 比赛链接:ICPC Asia Nanning 2017 题意 \(t\) 组样例,每组给出一个整数 \(n(2\le n\le 10^{50})\),求不大于 ...

  3. ICPC Asia Nanning 2017 F. The Chosen One (大数、规律、2的k次幂)

    Welcome to the 2017 ACM-ICPC Asia Nanning Regional Contest.Here is a breaking news. Now you have a c ...

  4. 2016 ACM/ICPC Asia Regional Dalian Online 1010 Weak Pair dfs序+分块

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submissio ...

  5. 2020 ICPC Asia Taipei-Hsinchu Regional Problem B Make Numbers (dfs搜索)

    题意:给你四个数字,你可以用这四个数字凑出四个1位数,一个2位数和两个1位数,或一个3位数和一个1位数,你可以用你凑出的数字进行\(+,-,x\)运算(所有运算符号至少出现一次),问你一共能得到多少个 ...

  6. 2017 ACM/ICPC Asia Regional Shenyang Online spfa+最长路

    transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 132768/1 ...

  7. 2017 ACM ICPC Asia Regional - Daejeon

    2017 ACM ICPC Asia Regional - Daejeon Problem A Broadcast Stations 题目描述:给出一棵树,每一个点有一个辐射距离\(p_i\)(待确定 ...

  8. 2017 ACM - ICPC Asia Ho Chi Minh City Regional Contest

    2017 ACM - ICPC Asia Ho Chi Minh City Regional Contest A - Arranging Wine 题目描述:有\(R\)个红箱和\(W\)个白箱,将这 ...

  9. 2017 ACM/ICPC Asia Regional Qingdao Online

    Apple Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submi ...

随机推荐

  1. python pymouse用法记录

    from pymouse import PyMouse m = PyMouse() m.position()#获取当前坐标的位置 m.move(x,y)#鼠标移动到xy位置 m.click(x,y)# ...

  2. “void * __cdecl operator new(unsigned int)”(??2@YAPAXI@Z) already defined in LIBCMTD.lib(new.obj)

    转自VC错误:http://www.vcerror.com/?p=1377 问题描述: 当 C 运行时 (CRT) 库和 Microsoft 基础类 (MFC) 库的链接顺序有误时,可能会出现以下 L ...

  3. 微信小程序,获取二维码

    微信小程序,获取二维码 找到一篇很实用的博客,他已经写得很详细了,自己也懒得写,亲测有效 参考网址

  4. Jmeter beanshell断言 org.json.jar包下载

    链接:https://pan.baidu.com/s/1O01ODjlKyqmz2NyDT0MCww 提取码:a5va 欢迎关注微信公众号:软件测试汪,qq技术交流群:809111560

  5. appium 环境搭建(不推荐安装此版本appium,推荐安装appium desktop)

    一:安装node.js 1.双击这个软件 2.一键安装,全都下一步,不要私自更改安装路径 3.打开cmd,输入npm,出现如下截图表示成功 二:安装appium 1.双击appium-installe ...

  6. PAT甲级——A1146 TopologicalOrder【25】

    This is a problem given in the Graduate Entrance Exam in 2018: Which of the following is NOT a topol ...

  7. VIP视频下载终结器

    youtube-dl: Youtube-dl是谷歌github上的一个开源项目,它是一款轻量级的命令行 下载实用工具,阿刚曾在乐软博客里文章<不仅仅是youtube,youtube-dl在线视频 ...

  8. gitlab+gitlab-ci+docker自动化部署

    导言 本次测试用的是gitlab-ci,单纯与gitlab搭配而言,gitlab-ci较jenkins更加一体,顺畅. 主机1:192.168.100.151 gitlab 主机2:192.168.1 ...

  9. bootstrap学习(五)代码

    内联代码: <code>public static</code>void main 用户输入: to edit setting,press <kbd><kbd ...

  10. MockServer

    基于Flask实现的一个简易Mock平台,使用标准json结构体编写Mock Api https://github.com/yinquanwang/MockServer   Key Features ...