【链接】http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1921
【题意】给一个图,图中数值为炸弹的威力k(为0则该格没有炸弹),每个炸弹爆炸会引爆其【左侧k个格子】和【上方全部格子】,问最少手动引爆几个炸弹能使所有炸弹都炸
【思路】
一个炸弹只能引爆其左侧和上侧,那么下方和右方没有炸弹的炸弹必然需要手动引爆
这个遍历的过程就是从逆序扫,从最右下角依次从右到左从下到上的顺序引爆
每引爆一个,调用函数完成剩下的连锁反应。
设置三个简单的函数:explore(),explore_left(),explore_up()
其中explore()调用explore_left()和explore_up()
explore_left()和explore_up()又分别调用了explore()
……总之忍着没搜题解直接就这么做了,对bfs有抗拒感,还是自己模拟了一下引爆过程比较符合正常人思维【误
【代码】
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <math.h>
#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
#define MAX_LEN 1005
#define ll long long
#define mod 100000007
#define MEM(a,al) memset(a,al,sizeof(a))
#define sfx(x) scanf("%lf",&x)
#define sfxy(x,y) scanf("%lf%lf",&x,&y)
#define sdx(x) scanf("%d",&x)
#define sdxy(x,y) scanf("%d%d",&x,&y)
#define pfx(x) printf("%.0f\n",x)
#define pfxy(x,y) printf("%.6f %.6f\n",x,y)
#define pdx(x) printf("%d\n",x)
#define pdxy(x,y) printf("%d %d\n",x,y)
#define getArray(a,len) for(int ia = 0; ia < len; ia++) scanf("%d",&a[ia])
#define printArray(a,len) for(int ia = 0; ia < len; ia++) printf("%d%c",a[ia],(ia==len-1)?'\n':' ')
#define fora(i,n) for(i = 0; i < n; i++)
#define fora1(i,n) for(i = 1; i <= n; i++)
#define foraf(i,n) for(int i = 0; i < n; i++)
#define foraf1(i,n) for(int i = 1; i <= n; i++)
#define ford(i,n) for(i = n-1; i >= 0; i--)
#define ford1(i,n) for(i = n; i > 0; i--)
#define fordf(i,n) for(int i = n-1; i >= 0; i--)
#define fordf1(i,n) for(int i = n; i > 0; i--)
class WriteInfo{
public:
void info() { printf("[Info] "); }
void infoEnd() { printf(" [/Info]\n"); }
} W;
const int INF = 1<<29;
const double INFD = 1e20;
const double eps = 1e-6;
int n,m;
int a[MAX_LEN][MAX_LEN], g[MAX_LEN][MAX_LEN];
int total, co;
void explode_left(int i, int jj){
void explode(int i, int j);
for(int j = jj-1; j >= max(jj-a[i][jj], 0); j--){
if (co >= total) return;
explode(i,j);
}
}
void explode_up(int ii, int j){
void explode(int i, int j);
for(int i = ii-1; i >= 0; i--){
if (co >= total) return;
explode(i,j);
}
}
void explode(int i, int j){
if (!g[i][j]) return;
co++;
if (co >= total) return;
g[i][j] = 0;
explode_left(i,j);
explode_up(i,j);
}
int main() {
int i,j,k;
int T;
while(~sdxy(n,m)){
fora(i,n)
fora(j,m){
sdx(a[i][j]);
g[i][j] = a[i][j] > 0 ? 1 : 0;
total += g[i][j];
}
co = 0;
int res = 0;
ford(i,n)
ford(j,m){
// 手动引爆
if (g[i][j]){
res++;
explode(i,j);
}
}
pdx(res);
}
return 0;
}