avatar
fireworks99
keep hungry keep foolish

FZU 2150 Fire Game

Description

今有草地一片,’#’为草,’.’为空地,草可燃,地不可。有二童子顽劣之至,以焚尽草地为娱。二人可于两处分别点火,瞬间即燃。火势凶猛,所到之处,寸草不生。凡火所在,唯待一刻,便四处蔓延。问:待草烧尽,耗时几何?

思路

各种点火组合皆遍历一遍,找出最优解。

BFS:将两个起点一起放入队列中遍历,vis数组标记该点是否已燃。检查终点,若所有草地被燃,答案即为终点时的time(我曾想问:若终点之前的某点以满足条件(即所有草地皆已燃),那答案是不是会更小些?后来想想这个点就是终点,vis尽被标记找不到其他点了)

吐槽

我也太那啥那啥了…一点不那啥…还是太那啥了…

刚开始想着两个点”分别“但“同时“bfs,还担心一个vis不够用(这个火燃到这里应该允许另一个火也可以经过这),后来想想,都是火,分啥你我啊!

Code

#include <queue>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;

int n, m;
string s[15];
bool flag;
bool vis[15][15];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

int tot;
struct grass
{
    int x, y;
} g[105];

struct node
{
    int x, y, tim;
};

bool check()
{
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < m; ++j)
        {
            if(!vis[i][j] && s[i][j] == '#')///有草地剩余
                return 0;
        }
    return 1;
}

int bfs(grass a, grass b)
{
    queue<node> q;
    node first, nxt;
    first.x = a.x;
    first.y = a.y;
    first.tim = 0;
    vis[a.x][a.y] = 1;
    q.push(first);
    first.x = b.x;
    first.y = b.y;
    first.tim = 0;
    vis[b.x][b.y] = 1;
    q.push(first);
    while(q.size())
    {
        first = q.front();
        q.pop();
        for(int i = 0; i < 4; ++i)
        {
            int xx = first.x + dx[i];
            int yy = first.y + dy[i];
            if(xx >= 0 && xx < n && yy >= 0 && yy < m && !vis[xx][yy] && s[xx][yy] == '#' )
            {
                vis[xx][yy] = 1;
                nxt.x = xx;
                nxt.y = yy;
                nxt.tim = first.tim + 1;
                q.push(nxt);
            }
        }
    }
    if(check())
        return first.tim;
    return inf;
}

int main()
{
//    freopen("00in.txt", "r", stdin);
    int t;
    cin >> t;
    int tem = t;
    while(t--)
    {
        tot = 0;
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; ++i)
            cin >> s[i];
        for(int i = 0; i < n; ++i)
            for(int j = 0; j < m; ++j)
                if(s[i][j] == '#')
                {
                    g[tot].x = i;
                    g[tot].y = j;
                    tot++;
                }
        flag = 0;
        int ans = inf;
        for(int i = 0; i < tot; ++i)
            for(int j = i; j < tot; ++j)///j == i不能漏(只有一处可点的地方)
            {
                memset(vis, 0, sizeof(vis));
                int res = bfs(g[i], g[j]);
                if(res < ans)
                    ans = res;
            }
        if(ans == inf)
            cout << "Case " << tem - t << ": -1" << '\n';
        else
            cout << "Case " << tem - t << ": " << ans << '\n';
    }
    return 0;
}

Just say something I want to say

刚开始做这题有自己的想法,然后发现漏洞,各种弥补,一点一点添置,一点一点改进,结果写了二百多行,写了三天还是…写的江郎才尽没办法了看了一眼题解,原来想多了,一些地方没想明白整的很复杂…

这让我想起高中的时候,那时候要想得高分倡导多做题,不要吊死在一棵树上。可我做不到,这道题我有想法,付出再多精力与时间把它做出来也是值得的。可事实是即使这样我也做不出来,然而负反馈调节就出现了:我都付出那么多了必须把它做出来,可我就是做不出来,如果此时放弃那么岂不前功尽弃,如果此时不放弃岂不浪费更多时间…

这好像是心理学的某个定理(也可能不是):你买了一张电影票,看了一会儿发现电影不怎么样,甚至有些厌恶,这时候明明可以离开的,可转念一想:钱都花了,不看完好像损失了什么。然而最终事实是:你浪费了时间去做了自己讨厌的事,一切似乎只是因为“患得患失”的性格?以说:当断则断?(能屈能伸?张弛有度?)说起来倒容易……

贴一些废代码泄愤(勿看)

#include <set>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int inf = 0x3f3f3f3f;

int n, m;
bool flag;///BFS can't find the answer,output "-1".
string s[15];
bool vis1[15][15];
bool vis2[15][15];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
int zc[4];
int zd[4];///从某点出发可以走四个方向,起初自作聪明写3

int tot;
struct grass
{
    int x, y;
} g[105];

struct node
{
    int x, y, tim;
    set<int> st;///存放当前状态已燃之草的序号
} ;

int bfs(grass c, grass d)
{
    bool flag1 = 0;
    bool flag2 = 0;
    node nowc, nowd, nxtc[4], nxtd[4], last1, last2;

    nowc.x = c.x;
    nowc.y = c.y;
    nowc.tim = 0;
    for(int i = 0; i < tot; ++i)
        if(g[i].x == c.x && g[i].y == c.y)
        {
            nowc.st.insert(i);
            break;
        }
    vis1[c.x][c.y] = 1;
    queue<node> q1;
    q1.push(nowc);

    nowd.x = d.x;
    nowd.y = d.y;
    nowd.tim = 0;
    for(int i = 0; i < tot; ++i)
        if(g[i].x == d.x && g[i].y == d.y)
        {
            nowd.st.insert(i);
            break;
        }
    vis2[d.x][d.y] = 1;
    queue<node> q2;
    q2.push(nowd);

    while(q1.size() || q2.size())
    {
        ///取队列首元素
        if(q1.size() == 1)
            last1 = q1.front();
        if(q2.size() == 1)
            last2 = q2.front();
        if(q1.empty())
            nowc = last1;
        else
        {
            flag1 = 1;
            nowc = q1.front();
            q1.pop();
        }
        if(q2.empty())
            nowd = last2;
        else
        {
            flag2 = 1;
            nowd = q2.front();
            q2.pop();
        }

        cout << "have a check : " << '\n';
        cout << "nowc " << nowc.x << ' ' << nowc.y << ' ' << nowc.tim << ' ' << nowc.st.size() << '\n';
        cout << "nowd " << nowd.x << ' ' << nowd.y << ' ' << nowd.tim << ' ' << nowd.st.size() << '\n';
        ///出口判断
        if(nowc.st.size() + nowd.st.size() >= tot)
        {
            cout << "It seems to be a exit." << '\n';
            set<int> totst = nowc.st;
            for(set<int> ::iterator it = nowd.st.begin(); it != nowd.st.end(); ++it)
                totst.insert(*it);
            cout << "tot : " << totst.size() << '\n';
            if(totst.size() == tot)
            {
                flag = 1;
                cout << "The ans is : " << nowc.tim + nowd.tim << '\n';
                return nowc.tim + nowd.tim;
            }
//            flag = 1;
//            if(nowc.st.size() == tot && nowd.st.size() != tot)
//            {
//                cout << "The ans is : " << nowc.tim << '\n';
//                return nowc.tim;
//            }
//            else if(nowd.st.size() == tot && nowc.st.size() != tot)
//            {
//                cout << "The ans is : " << nowd.tim << '\n';
//                return nowd.tim;
//            }
//            else
//            {
//                cout << "The ans is : " << min(nowc.tim, nowd.tim) << '\n';
//                return min(nowc.tim, nowd.tim);
//            }
        }

        ///搜索nxt
        int zcnum = 0;
        int zdnum = 0;
        memset(zc, 0, sizeof(zc));
        memset(zd, 0, sizeof(zd));
        int nxtcnum = 0;
        int nxtdnum = 0;
        for(int i = 0; i < 4; ++i)
        {
            int xx, yy;
            if(flag1)
            {
                xx = nowc.x + dx[i];
                yy = nowc.y + dy[i];
                if(xx >= 0 && xx < n && yy >= 0 && yy < m && !vis1[xx][yy] && s[xx][yy] == '#')
                {
                    vis1[xx][yy] = 1;
                    nxtc[nxtcnum].x = xx;
                    nxtc[nxtcnum].y = yy;
                    nxtcnum++;
//                    nxtc.tim = nowc.tim + 1;
//                    nxtc.st = nowc.st;
                    for(int j = 0; j < tot; ++j)
                        if(g[j].x == xx && g[j].y == yy)
                        {
                            zc[zcnum++] = j;
                            break;
                        }
//                    q1.push(nxtc);
                }
            }
            if(flag2)
            {
                xx = nowd.x + dx[i];
                yy = nowd.y + dy[i];
                if(xx >= 0 && xx < n && yy >= 0 && yy < m && !vis2[xx][yy] && s[xx][yy] == '#')
                {
                    vis2[xx][yy] = 1;
                    nxtd[nxtdnum].x = xx;
                    nxtd[nxtdnum].y = yy;
                    nxtdnum++;
//                    nxtd.tim = nowd.tim + 1;
//                    nxtd.st = nowd.st;
                    for(int j = 0; j < tot; ++j)
                        if(g[j].x == xx && g[j].y == yy)
                        {
                            zd[zdnum++] = j;
                            break;
                        }
//                    q2.push(nxtd);
                }
            }
        }
        for(int i = 0; i < nxtcnum; ++i)
        {
            nxtc[i].tim = nowc.tim + 1;
            nxtc[i].st = nowc.st;
            for(int j = 0; j < zcnum; ++j)
                nxtc[i].st.insert(zc[j]);
            q1.push(nxtc[i]);
        }
        for(int i = 0; i < nxtdnum; ++i)
        {
            nxtd[i].tim = nowd.tim + 1;
            nxtd[i].st = nowd.st;
            for(int j = 0; j < zdnum; ++j)
                nxtd[i].st.insert(zd[j]);
            q2.push(nxtd[i]);
        }
    }
    cout << "There is no solution!" << '\n';
    return inf;
}

int main()
{
    int t;
    freopen("00in.txt", "r", stdin);
    cin >> t;
    int tem = t;
    while(t--)
    {
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; ++i)
            cin >> s[i];
        tot = 0;
        for(int i = 0; i < n; ++i)
            for(int j = 0; j < m; ++j)
                if(s[i][j] == '#')
                {
                    g[tot].x = i;
                    g[tot].y = j;
                    tot++;
                }
        if(tot <= 2)
        {
            if(tot > 0)
            {
                cout << "the number of the grass is less than 3" << '\n';
                cout << "Case :" << tem - t << ": 0" << '\n';
            }
            else
            {
                cout << "there is no grass!" << '\n';
                cout << "Case :" << tem - t << ": -1" << '\n';
            }
        }
        else
        {
            int ans = inf;
            flag = 0;///0表示无合适方案
            for(int i = 0; i < tot; ++i)
                for(int j = i + 1; j < tot; ++j)
                {
                    cout << "The new solution for this question :" << '\n';
                    cout << "position :" << g[i].x << ' ' << g[i].y << ' ' << g[j].x << ' ' << g[j].y << '\n';
                    memset(vis1, 0, sizeof(vis1));
                    memset(vis2, 0, sizeof(vis2));
                    int res = bfs(g[i], g[j]);
                    if(res < ans)
                        ans = res;
                }
            if(flag)
                cout << "Case :" << tem - t << ": " << ans << '\n';
            else
                cout << "Case :" << tem - t << ": -1" << '\n';
        }
    }
    return 0;
}
#include <set>
#include <queue>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int inf = 0x3f3f3f3f;

int n, m;
bool flag;///BFS can't find the answer,output "-1".
string s[15];
bool vis1[15][15];
bool vis2[15][15];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
int zc[4];
int zd[4];///从某点出发可以走四个方向,起初自作聪明写3

int tot;
struct grass
{
    int x, y;
} g[105];

struct node
{
    int x, y, tim;
    set<int> st;///存放当前状态已燃之草的序号
} ;

int bfs(grass c, grass d)
{
    bool flag1 = 0;
    bool flag2 = 0;
    node nowc, nowd, nxtc, nxtd, last1, last2;

    nowc.x = c.x;
    nowc.y = c.y;
    nowc.tim = 0;
    for(int i = 0; i < tot; ++i)
        if(g[i].x == c.x && g[i].y == c.y)
        {
            nowc.st.insert(i);
            break;
        }
    vis1[c.x][c.y] = 1;
    queue<node> q1;
    q1.push(nowc);

    nowd.x = d.x;
    nowd.y = d.y;
    nowd.tim = 0;
    for(int i = 0; i < tot; ++i)
        if(g[i].x == d.x && g[i].y == d.y)
        {
            nowd.st.insert(i);
            break;
        }
    vis2[d.x][d.y] = 1;
    queue<node> q2;
    q2.push(nowd);

    while(q1.size() || q2.size())
    {
        ///取队列首元素
        if(q1.size() == 1)
            last1 = q1.front();
        if(q2.size() == 1)
            last2 = q2.front();
        if(q1.empty())
            nowc = last1;
        else
        {
            flag1 = 1;
            nowc = q1.front();
            q1.pop();
        }
        if(q2.empty())
            nowd = last2;
        else
        {
            flag2 = 1;
            nowd = q2.front();
            q2.pop();
        }

        cout << "have a check : " << '\n';
        cout << "nowc " << nowc.x << ' ' << nowc.y << ' ' << nowc.tim << ' ' << nowc.st.size() << '\n';
        cout << "nowd " << nowd.x << ' ' << nowd.y << ' ' << nowd.tim << ' ' << nowd.st.size() << '\n';
        ///出口判断
//        if(nowc.st.size() + nowd.st.size() >= tot)
//        {
//            cout << "It seems to be a exit." << '\n';
//            set<int> totst = nowc.st;
//            for(set<int> ::iterator it = nowd.st.begin(); it != nowd.st.end(); ++it)
//                totst.insert(*it);
//            cout << "tot : " << totst.size() << '\n';
//            if(totst.size() == tot)
//            {
//                flag = 1;
//                cout << "The ans is : " << nowc.tim + nowd.tim << '\n';
//                return nowc.tim + nowd.tim;
//            }
//            flag = 1;
//            if(nowc.st.size() == tot && nowd.st.size() != tot)
//            {
//                cout << "The ans is : " << nowc.tim << '\n';
//                return nowc.tim;
//            }
//            else if(nowd.st.size() == tot && nowc.st.size() != tot)
//            {
//                cout << "The ans is : " << nowd.tim << '\n';
//                return nowd.tim;
//            }
//            else
//            {
//                cout << "The ans is : " << min(nowc.tim, nowd.tim) << '\n';
//                return min(nowc.tim, nowd.tim);
//            }
//        }

        ///搜索nxt
//        int zcnum = 0;
//        int zdnum = 0;
//        memset(zc, 0, sizeof(zc));
//        memset(zd, 0, sizeof(zd));
//        int nxtcnum = 0;
//        int nxtdnum = 0;
        for(int i = 0; i < 4; ++i)
        {
            int xx, yy;
            if(flag1)
            {
                xx = nowc.x + dx[i];
                yy = nowc.y + dy[i];
                if(xx >= 0 && xx < n && yy >= 0 && yy < m && !vis1[xx][yy] && s[xx][yy] == '#')
                {
                    vis1[xx][yy] = 1;
                    nxtc.x = xx;
                    nxtc.y = yy;
                    nxtc.tim = nowc.tim + 1;
                    nxtc.st = nowc.st;
                    for(int j = 0; j < tot; ++j)
                        if(g[j].x == xx && g[j].y == yy)
                        {
                            nxtc.st.insert(j);
                            break;
                        }
                    q1.push(nxtc);
                }
            }
            if(flag2)
            {
                xx = nowd.x + dx[i];
                yy = nowd.y + dy[i];
                if(xx >= 0 && xx < n && yy >= 0 && yy < m && !vis2[xx][yy] && s[xx][yy] == '#')
                {
                    vis2[xx][yy] = 1;
                    nxtd.x = xx;
                    nxtd.y = yy;
                    nxtd.tim = nowd.tim + 1;
                    nxtd.st = nowd.st;
                    for(int j = 0; j < tot; ++j)
                        if(g[j].x == xx && g[j].y == yy)
                        {
                            nxtd.st.insert(j);
                            break;
                        }
                    q2.push(nxtd);
                }
            }
        }
//        for(int i = 0; i < nxtcnum; ++i)
//        {
//            nxtc[i].tim = nowc.tim + 1;
//            nxtc[i].st = nowc.st;
//            for(int j = 0; j < zcnum; ++j)
//                nxtc[i].st.insert(zc[j]);
//            q1.push(nxtc[i]);
//        }
//        for(int i = 0; i < nxtdnum; ++i)
//        {
//            nxtd[i].tim = nowd.tim + 1;
//            nxtd[i].st = nowd.st;
//            for(int j = 0; j < zdnum; ++j)
//                nxtd[i].st.insert(zd[j]);
//            q2.push(nxtd[i]);
//        }
    }

    cout << "There is no solution!" << '\n';
    return inf;
}

int main()
{
    int t;
    freopen("00in.txt", "r", stdin);
    cin >> t;
    int tem = t;
    while(t--)
    {
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; ++i)
            cin >> s[i];
        tot = 0;
        for(int i = 0; i < n; ++i)
            for(int j = 0; j < m; ++j)
                if(s[i][j] == '#')
                {
                    g[tot].x = i;
                    g[tot].y = j;
                    tot++;
                }
        if(tot <= 2)
        {
            if(tot > 0)
            {
                cout << "the number of the grass is less than 3" << '\n';
                cout << "Case :" << tem - t << ": 0" << '\n';
            }
            else
            {
                cout << "there is no grass!" << '\n';
                cout << "Case :" << tem - t << ": -1" << '\n';
            }
        }
        else
        {
            int ans = inf;
            flag = 0;///0表示无合适方案
            for(int i = 0; i < tot; ++i)
                for(int j = i + 1; j < tot; ++j)
                {
                    cout << "The new solution for this question :" << '\n';
                    cout << "position :" << g[i].x << ' ' << g[i].y << ' ' << g[j].x << ' ' << g[j].y << '\n';
                    memset(vis1, 0, sizeof(vis1));
                    memset(vis2, 0, sizeof(vis2));
                    int res = bfs(g[i], g[j]);
                    if(res < ans)
                        ans = res;
                }
            if(flag)
                cout << "Case :" << tem - t << ": " << ans << '\n';
            else
                cout << "Case :" << tem - t << ": -1" << '\n';
        }
    }
    return 0;
}
#include <queue>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;

int n, m, ans;
bool flag;///针对 “-1”
string s[15];
bool vis1[15][15];
bool vis2[15][15];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

struct node
{
    int x, y, step;
} a[100];

int tot;
struct grass
{
    int x, y;
} g[100];

int bfs(grass c, grass d)
{
    int num = 2;
    node now1, now2, nxt1, nxt2;
    int ans_step = 0;

    now1.x = c.x;
    now1.y = c.y;
    now1.step = 0;
    vis1[c.x][c.y] = 1;

    now2.x = d.x;
    now2.y = d.y;
    now2.step = 0;
    vis2[d.x][d.y] = 1;

    queue<node> q1;
    queue<node> q2;
    q1.push(now1);
    q2.push(now2);

    while(q1.size() || q2.size())///刚开始记错了写成&&
    {
//        cout << "Check the size : " << '\n';
//        cout << q1.size() << ' ' << q2.size() << '\n';
        bool flag1 = 0;
        bool flag2 = 0;
        bool flag_front = 0;
        if(q1.size())
        {
            flag1 = 1;
            now1 = q1.front();
            q1.pop();
        }
        if(q2.size())
        {
            flag2 = 1;
            now2 = q2.front();
            q2.pop();
        }

        int xx, yy;
        for(int i = 0; i < 4; ++i)
        {
            if(flag1)
            {
                xx = now1.x + dx[i];
                yy = now1.y + dy[i];
                if(xx >= 0 && xx < n && yy >= 0 && yy < m && s[xx][yy] == '#' && !vis1[xx][yy])
                {
                    vis1[xx][yy] = 1;
                    nxt1.x = xx;
                    nxt1.y = yy;
                    nxt1.step = now1.step + 1;
                    q1.push(nxt1);
                    if(!vis2[xx][yy])
                    {
                        cout << "num++ 's position" << xx << ' ' << yy << '\n';
                        num++;
                        flag_front = 1;
                        if(num == tot)
                        {
                            flag = 1;
                            return nxt1.step + now2.step;
                        }
                    }
                }
            }
            if(flag2)
            {
                xx = now2.x + dx[i];
                yy = now2.y + dy[i];
                if(xx >= 0 && xx < n && yy >= 0 && yy < m && s[xx][yy] == '#' && !vis2[xx][yy])
                {
                    vis2[xx][yy] = 1;
                    nxt2.x = xx;
                    nxt2.y = yy;
                    nxt2.step = now2.step + 1;
                    q2.push(nxt2);
                    if(!vis1[xx][yy])
                    {
                        cout << "num++ 's position" << xx << ' ' << yy << '\n';
                        num++;
                        if(num == tot)
                        {
                            flag = 1;
                            if(flag_front)
                            return nxt1.step + nxt2.step;
                            else
                            return now1.step + nxt2.step;
                        }
                    }
                }
            }
        }
    }
//    cout << "There is not a right method!" << '\n';
//    cout << "num :" << num <<'\n';
    return inf;
}

int main()
{
    int t;
    freopen("00in.txt", "r", stdin);
    cin >> t;
    int tem = t;
    while(t--)
    {
        tot = 0;
        flag = 0;
        ans = inf;
        scanf("%d%d", &n, &m);
        for(int i = 0; i < n; ++i)
            cin >> s[i];
        for(int i = 0; i < n; ++i)
            for(int j = 0; j < m; ++j)
            {
                if(s[i][j] == '#')
                {
                    g[tot].x = i;
                    g[tot].y = j;
                    tot++;
                }
            }
//        cout << "Check the grass : " << '\n';
//        for(int i = 0; i < tot; ++i)
//            cout << g[i].x << ' ' << g[i].y << '\n';
        if(tot <= 2)
        {
//            cout << "The number of grass is less than 3." << '\n';
            if(tot > 0)
                cout << "Case " << tem - t << ": 0" << '\n';
            else
                cout << "Case " << tem - t << ": -1" << '\n';
        }
        else
        {
//            cout << "Check the dapei : " << '\n';
            for(int i = 0; i < tot; ++i)
                for(int j = i + 1; j < tot; ++j)
                {
                    cout << i << ' ' << j << '\n';
                    cout << "position : " << g[i].x << ' ' << g[i].y << ' ' << g[j].x << ' ' << g[j].y << '\n';
                    memset(vis1, 0, sizeof(vis1));
                    memset(vis2, 0, sizeof(vis2));
                    int res = bfs(g[i], g[j]);
                    cout << "Check the bfs : " << res << '\n';
                    if(res < ans)
                        ans = res;
                }
            if(flag)
                cout << "Case " << tem - t << ": " << ans << '\n';
            else
                cout << "Case " << tem - t << ": -1" << '\n';
        }
    }
    return 0;
}
Site by Baole Zhao | Powered by Hexo | theme PreciousJoy