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;
}
posted @ 2020-01-13 12:36  lifehappy  阅读(55)  评论(0编辑  收藏  举报