zoukankan      html  css  js  c++  java
  • FZU

    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;
    }
    
  • 相关阅读:
    进程、线程和协程的区别(转)
    IO多路复用机制(转)
    防火墙及其功能(转)
    TCP连接的建立和终止。
    TCP和UDP细致刻画,区别。
    typename T和class T区别与联系
    TCP UDP的详解开始 ----UNIX网络编程
    关于UNIX网络编程的的OSI,1.7章的总结
    UNIX网络编程daytime服务端和客户端的实现过程
    linux shell脚本执行错误:bad substitution
  • 原文地址:https://www.cnblogs.com/lifehappy/p/12604372.html
Copyright © 2011-2022 走看看