P2484 [SDOI2011]打地鼠 题解
P2484 [SDOI2011]打地鼠 题解
题目
分析
锤子每次只能将每个洞里打掉一只地鼠,所以对于每次击打,都会打掉
因为每只地鼠都需要被干掉,所以如果当前方案成立,总可以通过不断在地图左上角寻找有地鼠的洞,再以这个洞为锤子击打的范围的左上角进行击打来打完所有地鼠。
而如果在打地鼠的时候发现击打范围内有已经没有地鼠的洞或者会打到地图外面的话,当前方案就不成立。
思路
由于地图只是个
根据上文的分析,我们只需要在整个地图左上角找到一个还剩的有地鼠的洞,设这个洞的坐标为
- 判断
是否在地图外面。在的话说明这个锤子不满足题意,结束,否则进行下一步。 - 判断
到 范围内有没有空地鼠洞。如果有的话,说明这个锤子不满足题意,结束,否则进行下一步。 - 将
到 范围内的地鼠数量减一。 - 将这个锤子的击打总次数加一。
- 回到第
步操作直到所有地鼠洞为空。
因为
最后就输出所有可行的锤子中击打次数最小的值就好了。更详细的解释请参阅代码里的注释。
代码
#pragma GCC optimize(2)
#include <cstdio>
using namespace std;
int n, m, tot = 0;
long long ans = 1145141919810;
int maze[105][105];
int tmaze[105][105]; //因为要尝试多次且每次尝试都会修改地鼠洞内地鼠的数量,
//我们需要在每次尝试前复制原始的地图
long long Min(long long a, long long b)
{
return a > b ? b : a;
}
inline bool findfirst(int &x, int &y) //从地图左上角找到第一个有地鼠的地鼠洞,返回是否找到
{
for (register int i = 1; i <= n; i++)
{
for (register int j = 1; j <= m; j++)
{
if (tmaze[i][j])
{
x = i, y = j; //找到就将这个洞的坐标传回去
return 1;
}
}
}
return 0;
}
inline void dfs(int r, int c, int cnt) //参数表示锤子大小和花费
{
int x, y; //用x,y表示目前在左上角找到的地鼠洞为(x,y)
if (!findfirst(x, y)) //如果没找到有地鼠的洞说明找完了,更新答案并结束
{
ans = Min(ans, 1ll * cnt);
return;
}
if (x + r - 1 > n || y + c - 1 > m || cnt >= ans) //操作1,如果要打左上角的地鼠
//洞锤子会超过地图,说明这组
//方案不成立
return;
int red = tmaze[x][y]; //操作3,将(x,y)到(x+r-1,y+c-1)内的地鼠数量都减去(x,y)内的地鼠数
for (register int i = x; i <= x + r - 1; i++)
{
for (register int j = y; j <= y + c - 1; j++)
{
tmaze[i][j] -= red;
if (tmaze[i][j] < 0) //操作2,如果这个洞里的地鼠数量为负说明这组方案不成立
return;
}
}
dfs(r, c, cnt + red); //操作4、5,加上操作次数,继续打剩下的地鼠
return;
}
void cpymaze()
{
for (register int i = 1; i <= n; i++)
for (register int j = 1; j <= m; j++)
tmaze[i][j] = maze[i][j]; //复制原始的地图
}
signed main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
scanf("%d", &maze[i][j]);
tot += maze[i][j]; //记录地鼠总数
}
}
for (int r = 1; r <= n; r++)
{
for (int c = 1; c <= m; c++)
{
if (tot % (r * c) == 0) //分析中所说的,只有锤子的覆盖大小能整除地鼠总数才行
{
cpymaze();
dfs(r, c, 0);
}
}
}
printf("%lld\n", ans);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】