https://blog.csdn.net/weixin_39278265/article/details/80930233
ccf能力认证(201803-4)
问题描述
试题编号: | 201803-4 |
试题名称: | 棋局评估 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 Alice和Bob正在玩井字棋游戏。 输入格式 输入的第一行包含一个正整数T,表示数据的组数。 输出格式 对于每组数据,输出一行一个整数,表示当前局面的得分。 样例输入 3 样例输出 3 样例说明 第一组数据: 数据规模和约定 对于所有评测用例,1 ≤ T ≤ 5。 |
题意:两人下井字棋,现在给你一个残局棋盘,两人都最优策略下棋,问最后分数情况。
思路:在搜索树中每个节点,下棋的人都选择对自己最有利的子树走。
#include
#include
#include
#include
using namespace std;
int a[3][3];
bool hok(int val,int x)
{
if(a[x][0]==val&&a[x][1]==val&&a[x][2]==val)
{
return true;
}
return false;
}
bool lok(int val,int y)
{
if(a[0][y]==val&&a[1][y]==val&&a[2][y]==val)
{
return true;
}
return false;
}
int check()
{
int ans = 0;
for(int i = 0;i<3;i++)
{
for(int j = 0;j<3;j++)
{
if(a[i][j]==0)ans++;
}
}
return ans;
}
int win(int x)
{
int w = 0,ans = 1;
if(hok(x,0)||hok(x,1)||hok(x,2))w=1;
if(lok(x,0)||lok(x,1)||lok(x,2))w=1;
if(a[0][0]==x&&a[1][1]==x&&a[2][2]==x)w=1;
if(a[0][2]==x&&a[1][1]==x&&a[2][0]==x)w=1;
if(!w)return 0;
ans +=check();
return ans*(x==1?1:-1);
}
int dfs(int p,int step)
{
if(step==0)
{
return 0;
}
int Min = 10,Max = -10;
for(int i = 0;i<3;i++)
{
for(int j =0;j<3;j++)
{
if(!a[i][j])
{
a[i][j] = p+1;
int w = win(p+1);
if(w)
{
a[i][j] =0;
return w>0?max(Max,w):min(Min,w);
}
else
{
if(!p)Max = max(Max,dfs(1,step-1));
else Min = min(Min,dfs(0,step-1));
}
a[i][j] = 0;
}
}
}
return p?Min:Max;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int cnt = 0;
for(int i = 0;i<3;i++)
{
for(int j = 0;j<3;j++)
{
scanf("%d",&a[i][j]);
if(a[i][j]==1)cnt++;
}
}
int x = win(1),y = win(2);
if(x){
printf("%d\n",x);
}
else if(y)
{
printf("%d\n",y);
}
else printf("%d\n",dfs(0,9-cnt*2));
}
}
计蒜客 rake_it_in
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 44×4 board is created with 16 values placed on the board. Starting with player Alice, each player in a round selects a 2 \times 22×2 region of the board, adding the sum of values in the region to the score indicator, and then rotating these four values 9090 degrees counterclockwise.
After 22k 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.
The input contains several test cases and the first line provides an integer t (1 \le t \le 200)t(1≤t≤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)k(1≤k≤3). Each of the following four lines contains four integers indicating the values on the board initially. All values are integers between 11 to 1010.
For each case, output an integer in a line which is the predicted final score.
样例输入
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
样例输出
20 40 63 71
题意:两人对一个4x4的矩阵每一回合每个人都做同样的操作(选择一个2x2的子矩阵,将其和加入sum中,并将其逆时针90度翻转),一个人想要结束后sum值大,一个人想要sum值小,问最后sum值是多少。
思路:类似。
#include
#include
#include
#include
using namespace std;
int a[4][4];
int k1;
void rotate(int i,int j,int type)
{
int tmp;
if(type==-1)
{
tmp = a[i][j];
a[i][j] = a[i+1][j];
a[i+1][j] = a[i+1][j+1];
a[i+1][j+1] = a[i][j+1];
a[i][j+1] = tmp;
}
else
{
tmp = a[i][j];
a[i][j] = a[i][j+1];
a[i][j+1] = a[i+1][j+1];
a[i+1][j+1] = a[i+1][j];
a[i+1][j] = tmp;
}
}
int dfs(int p,int k)
{
if(k==2*k1)
{
int Min = 0x3f3f3f3f;
for(int i = 0;i<3;i++)
{
for(int j = 0;j<3;j++)
{
int res = a[i][j]+a[i+1][j]+a[i][j+1]+a[i+1][j+1];
Min = min(Min,res);
}
}
return Min;
}
int Min = 0x3f3f3f3f,Max = 0;
for(int i = 0;i<3;i++)
{
for(int j = 0;j<3;j++)
{
int res = a[i][j]+a[i+1][j]+a[i][j+1]+a[i+1][j+1];
rotate(i,j,1);
if(p==0)
{
Max = max(Max,dfs(1,k+1)+res);
}
else
{
Min = min(Min,dfs(0,k+1)+res);
}
rotate(i,j,-1);
}
}
return ((!p)?Max:Min);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&k1);
for(int i = 0;i<4;i++)
{
for(int j = 0;j<4;j++)
{
scanf("%d",&a[i][j]);
}
}
printf("%d\n",dfs(0,1));
}
}