FZU - 2150 Fire Game
FZU - 2150 链接
这道题我原本的思路是判断有多少个连通块,然后通过连通块来判断时间的,
连通块大于2一定不可能烧毁所有的草;连通块等于2的时候,两个人分别放火,取用时最大值;连通块等于一的时候两个人同时处理一篇区域;没有连通块的时候直接输出0。
但是就是一直wa,我也找不出原因,可能是公式推错了吧。然后就采用以一种非常暴力的方法
数据量只有10 * 10,直接暴力四重循环来选择两个人放火的初始位置,然后通过bfs,来判断时间。
//Powered by CK
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef pair<int, int> PII;
const int ax[4] = {1, -1, 0, 0};
const int ay[4] = {0, 0, 1, -1};
const int INF = 0x3f3f3f3f;
int n, m, visit[20][20], maze[20][20];
bool judge(int x, int y) {
if(x >= 0 && x < n && y >= 0 && y < m && !visit[x][y] && maze[x][y])
return true;
return false;
}
int solve(int x1, int y1, int x2, int y2) {
int ans = -1;
memset(visit, 0, sizeof visit);
queue<PII> q;
q.push(make_pair(x1, y1)), q.push(make_pair(x2, y2));//两点入列
visit[x1][y1] = visit[x2][y2] = 1;
while(!q.empty()) {
int l = q.size();
for(int i = 0; i < l; i++) {//队列中的火开始延申
PII temp = q.front();
q.pop();
for(int j = 0; j < 4; j++) {
int tempx = temp.first + ax[j];
int tempy = temp.second + ay[j];
if(judge(tempx, tempy)) {
visit[tempx][tempy] = 1;
q.push(make_pair(tempx, tempy));
}
}
}
ans++;
}
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
if(maze[i][j] && !visit[i][j])//如果有草,并且火没有走过这个点,证明失败,返回INF无穷大
return INF;
return ans;
}
int main() {
// freopen("in.txt", "r", stdin);
ios::sync_with_stdio(false);
int t, x = 1;
char c;
cin >> t;
while(t--) {
cout << "Case " << x++ << ": ";
cin >> n >> m;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++) {
cin >> c;
if(c == '.') maze[i][j] = 0;
else maze[i][j] = 1;
}
int ans = INF;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
for(int k = 0; k < n; k++)
for(int l = 0; l < m; l++)
if(maze[i][j] == 1 && maze[k][l] == 1) {//初始放火位置必须是草
int now = solve(i, j, k, l);
ans = min(ans, now);
}
if(ans == INF) cout << "-1" << endl;//枚举所有放火点后还是不能点燃所有的草。
else cout << ans << endl;
}
return 0;
}
最后放上我wa了无数次的思路代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int ax[4] = {1, -1, 0, 0};
const int ay[4] = {0, 0, 1, -1};
const int N = 20;
int maze[N][N], num[N * N], cnt, maxn, n, m;
bool judge(int x, int y) {
if(x >= 0 && x < n && y >= 0 && y < m && !maze[x][y])
return true;
return false;
}
void dfs(int x, int y, int step) {
maxn = max(maxn, step);
for(int i = 0; i < 4; i++) {
int tempx = x + ax[i];
int tempy = y + ay[i];
if(judge(tempx, tempy)) {
maze[tempx][tempy] = 1;
dfs(tempx, tempy, step + 1);
}
}
}
int main() {
// freopen("in.txt", "r", stdin);
char c;
int t;
cin >> t;
int x = 1;
while(t--) {
printf("Case %d: ", x++);
cin >> n >> m;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++) {
cin >> c;
if(c == '#') maze[i][j] = 0;
else maze[i][j] = 1;
}
cnt = 0;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++) {
if(maze[i][j] == 0) {
maxn = 0;
maze[i][j] = 1;
dfs(i, j, 0);
num[cnt++] = maxn;
}
}
if(cnt > 2) cout << "-1" << endl;
else {
if(cnt == 2) cout << max(ceil((double)num[0] / 2.0), ceil((double)num[1] / 2.0)) << endl;
else if(cnt == 1) {
num[0] /= 2;
cout << ceil((double)num[0] / 2.0) << endl;
}
else cout << "0" << endl;
}
}
return 0;
}