题目
为了庆祝自己的生日,小张推出一款游戏。
游戏在一个20*20的方格上进行,上面有一些怪物,用#表示,其他是空格,用 . 表示。怪物有两点体力。
体力为0时死亡。 你可以进行以下操作:
(1)使一个横行上的怪物体力减一
(2)使一个竖行上的怪物体力减一
对每个横行或竖行只能操作一次,限定n次,问最多能杀死多少个怪物。
样例:
10
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
输出:
25
题解
在这个题目中,我们需要在一个 20×20 的方格内进行操作,方格中存在一些怪物(用 # 表示),这些怪物每个拥有 2 点体力。
我们可以通过执行操作来减少横行或竖行上怪物的体力,每行或每列的操作只能执行一次,并且有最多 ( n ) 次操作。
目标是计算在有限的操作次数内,最多能令多少个怪物的体力降至 0。
输入:第一行为一个整数 ( n ),表示可执行的操作次数。
随后是一个 20×20 的方格,以 # 和 . 表示怪物和空格。
输出:能击败的最大怪物数量。
程序结构
程序采用深度优先搜索(DFS)算法来探索不同的操作组合。
以下是程序的关键部分:
void dfs(int x,int y)
{
if(y>=m)return;
int t[25]={0},t1=0,t2=m-y;
for(int i=1;i<=20;i++)
{
t[c[i]]++;
}
for(int i=20;i>0;i--)
{
if(t==0)break;
if(t[i]<=t2)
{
t1+=t[i]*i;
t2-=t[i];
}
else
{
t1+=t2*i;
t2=0;
}
}
ans=max(ans,t1);
for(int i=x;i<=20;i++)
{
for(int j=1;j<=20;++j)
{
if(a[i][j])
{
c[j]++;
}
}
dfs(i+1,y+1);
for(int j=1;j<=20;++j)
{
if(a[i][j])
{
c[j]--;
}
}
}
return;
}
变量和数组定义:
n: 可操作的次数。
a[25][25]: 用于存储方格內怪物的体力,# 初始化为 2,. 初始化为 0。
c[25]: 计数器数组,用于记录每一列的怪物数量。
函数 dfs(int x, int y) 负责探索所有可能的操作组合。
在每次递归中,首先检查是否已进行 ( n ) 次操作。
记录当前的怪物数量,并尝试进行横行或竖行的操作,递归调用 dfs 函数。
最大怪物数量的计算:
每次操作后,通过 max 函数更新可击败的怪物最大数量。
ans: 存储能击败的最大怪物数量。
#include <iostream>
#include <queue>
using namespace std;
struct node
{
int x;
int y;
};
queue<node> q;
int n,m,sum;
char map[105][105];
int vist[105][105];
char buff[10005];
void acc(node no,int ox,int oy)
{
if(oy>=1&&ox>=1&&ox<=n&&oy<=m)
{
if(map[ox][oy]=='#'){
if(vist[ox][oy]==0){
vist[ox][oy]=no.x*m+no.y;
}
else if(vist[ox][oy]==no.x*m+no.y);
else{
sum++;
vist[ox][oy]=no.x*m+no.y;
}
}
else{
if( vist[ox][oy]==0){
vist[ox][oy]=1;
node newNode={ox,oy};
q.push(newNode);
}
}
}
}
void bfs(node no)
{
q.push(no);
while (!q.empty()) {
node ncur=q.front();
q.pop();
int ox,oy;
ox=ncur.x;
oy= ncur.y-1;
acc(no,ox,oy);
ox=ncur.x;
oy=ncur.y+1;
acc(no,ox,oy);
ox=ncur.x-1;
oy=ncur.y;
acc(no,ox,oy);
ox=ncur.x+1;
oy=ncur.y;
acc(no,ox,oy);
}
}
int main(){
cin>>n>>m;
for (int i=1;i<=n;i++){
cin>>buff;
for (int j=0;j<m;j++)
map[i][j+1]=buff[j];
}
node n11={1,1};
vist[1][1]=1;
bfs(n11);
node nmn={n,m};
vist[n][m]=1;
bfs(nmn);
cout<<sum;
return 0;
}
标签:体力,NHOI2011pj4,20,int,####################,怪物,操作
From: https://www.cnblogs.com/czhzeta/p/18540487