题目链接: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. leetcode上的一些分治算法

    53- 思路: 95- 思路

  2. NIO浅析(二)

    一:前言 在(一中了解了NIO中的缓冲区和通道),通过本文章你会了解阻塞和非阻塞,选择器,管道 二:完成NIO通信的三要素 * 1.通道(Channel):负责连接* java.nio.channel ...

  3. Leetcode代码复盘_分治法相关

    分治法 1.二分搜索(算法时间复杂度O(log n)) 输出:如果x=A[j],则输出j,否则输出0. 1.binarysearch(1,n) 过程:binarysearch(low,high) 1. ...

  4. log4j日志格式化

    Apache log4j 提供了各种布局对象,每一个对象都可以根据各种布局格式记录数据.另外,也可以创建一个布局对象格式化测井数据中的特定应用的方法. 所有的布局对象 - Appender对象收到 L ...

  5. jQuery选择器中空格的问题再探究

    jQuery选择器的空格问题,看似很小,但是差之毫厘谬以千里,让人很是恼火,<锋利的jQuery>书中有个经典的例子,我这里也拷贝下来,再加点自己的想法 <html> < ...

  6. PHP简单导出Excel表格

    <?php header('Content-Type: application/vnd.ms-excel'); header('Content-Disposition: attachment; ...

  7. 在Ubuntu中安装配置java后运行java -version时提示二进制文件不能执行

    因为jdk安装包有问题,试试32位的

  8. 【目录】Asp.NETCore轻松学系列

    随笔分类 - Asp.NETCore轻松学系列 Asp.NETCore轻松学系列阅读指引目录 摘要: 耗时两个多月,坚持写这个入门系列文章,就是想给后来者更好更快的上手体验,这个系列可以说是从入门到进 ...

  9. cordova 配置 高德地图sdk定位

    获取 sha1 打开 cmd 1. cd .android 2. keytool -list -v -keystore debug.keystore 3. 输入密钥: android 4. 复制 sh ...

  10. LeetCode Array Easy121. Best Time to Buy and Sell Stock

    Description Say you have an array for which the ith element is the price of a given stock on day i. ...