[kuangbin带你飞]专题一 【简单搜索】 【--完结--】

比赛链接:点击打开链接


A - 棋盘问题

AC代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int n, k, ans;
int che[10][10];
int vis[10];
void dfs(int row, int num)
{
    if(num == k)        //搜索到最后一个格子
    {
        ans++;
        return ;
    }
    if(row > n) return ;//越界
    for(int j = 1; j <= n; ++j)
        if(che[row][j] && !vis[j])
        {
            vis[j] = 1;
            dfs(row+1, num+1);
            vis[j] = 0;//搜索完成后归零
        }
    dfs(row+1, num);
    return ;
}

int main()
{
    char ch;
    while(~scanf("%d%d",&n,&k))
    {
        if(n == -1 && k == -1) break;
        ans = 0;
        memset(che, 0, sizeof(che));
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= n; ++i)
        {
            getchar();
            for(int j = 1; j <= n; ++j)
            {
                scanf("%c",&ch);
                if(ch == '#') che[i][j] = 1;
            }
        }
        dfs(1, 0); //第一行,符合条件的棋子数为0
        cout << ans << endl;
    }
    return 0;
}

B - Dungeon Master           

AC代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
int n, m, k, flag;
int startx, starty, startz;
int endx, endy, endz;
char e[35][35][35];
int nexta[6][3] = {{0,1,0},{0,-1,0},{1,0,0},{-1,0,0},{0,0,1},{0,0,-1} };
struct node
{
    int x, y, z;
    int sum;
};
int bfs(int a, int b, int c)
{
    node t1, t2, t3;
    queue<node> q;
    t1.x = a;
    t1.y = b;
    t1.z = c;
    t1.sum = 0;
    q.push(t1);
    while(!q.empty())
    {
        t2 = q.front();
        q.pop();
        for(int i = 0; i < 6; ++i)
        {
            t3.x = t2.x + nexta[i][0];
            t3.y = t2.y + nexta[i][1];
            t3.z = t2.z + nexta[i][2];
            t3.sum = t2.sum + 1;
            if(t3.x < 0 || t3.x >= n || t3.y < 0 || t3.y >= m || t3.z < 0 || t3.z >= k)//越界
                continue;
            if(e[t3.x][t3.y][t3.z] != '#')
            {
                if(t3.x == endx && t3.y == endy && t3.z == endz)
                {
                    flag = 1;
                    return t3.sum;
                }
                q.push(t3);
                e[t3.x][t3.y][t3.z] = '#';
            }
        }
    }
}
int main()
{
    while(scanf("%d%d%d",&n,&m,&k))
    {
        if(n == 0 && m == 0 && k == 0) break;
        for(int i = 0; i < n; ++i)
            for(int j = 0; j < m; ++j)
                for(int r = 0; r < k; ++r)
                {
                    cin >> e[i][j][r];
                    if(e[i][j][r] == 'S')
                    {
                        startx = i;
                        starty = j;
                        startz = r;
                    }
                    if(e[i][j][r] == 'E')
                    {
                        endx = i;
                        endy = j;
                        endz = r;
                    }
                }
        flag = 0;
        int sum = bfs(startx, starty, startz);
        if(flag == 1)
            cout << "Escaped in " << sum << " minute(s)." << endl;
        else
            cout << "Trapped!" << endl;
    }
    return 0;
}

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
using namespace std;
int n, k, ans;
int vis[200005];

struct pos
{
    int x, t;
};
queue<pos> s;

void bfs(int x)
{
    pos b;
    b.x = x;
    b.t = 0;
    vis[x] = 1;
    s.push(b);
    while(!s.empty())
    {
        pos tem = s.front();
        s.pop();
        if(tem.x == k)
        {
            ans = tem.t;
            return ;
        }
        pos nex;     //开始向目标方向搜索
        nex.x = tem.x + 1;
        if(nex.x >= 0 && nex.x <= 100000 && vis[nex.x] == 0)
        {
            nex.t = tem.t + 1;
            vis[nex.x] = 1;
            s.push(nex);
        }
        nex.x = tem.x - 1;
        if(nex.x >= 0 && nex.x <= 100000 && vis[nex.x] == 0)
        {
            nex.t = tem.t + 1;
            vis[nex.x] = 1;
            s.push(nex);
        }
        nex.x = tem.x * 2;
        if(nex.x >= 0 && nex.x <= 100000 && vis[nex.x] == 0)
        {
            nex.t = tem.t + 1;
            vis[nex.x] = 1;
            s.push(nex);
        }
    }
}

int main()
{
    while(~scanf("%d%d",&n, &k))
    {
        memset(vis, 0, sizeof(vis));
        while(!s.empty()) s.pop();

        bfs(n);
        cout << ans << endl;
    }
    return 0;
}


D - Fliptile                  

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
const int maxn = 16;
const int inf = 0x3f3f3f3f;
int m, n;
int cow[maxn][maxn];
int flip[maxn][maxn];
int opt[maxn][maxn];
int dir[][2] = {0, 0, 0, 1, 0, -1, -1, 0};

void getmap()
{
    for(int i = 0; i < m; ++i)
        for(int j = 0; j < n; ++j)
            scanf("%d",&cow[i][j]);
}

int getcolo(int x, int y)
{
    int tem = cow[x][y], xx, yy;
    for(int i = 0; i < 4; ++i)
    {
        xx = x + dir[i][0];
        yy = y + dir[i][1];
        if(xx >= 0 && xx < m && yy >= 0 && yy < n)
            tem += flip[xx][yy];
    }
    return tem & 1;
}

int dfs(int k)
{
    int sum, i, j;
    if(k == m -1)
    {
        for(i = 0; i < n; ++i)
            if(getcolo(k, i)) break;
        if(i != n) return -1;
        for(i = sum = 0; i < m; ++i)
            for(j = 0; j < n; ++j)
                if(flip[i][j]) sum++;
        return sum;
    }
    for(int j = 0; j < n; ++j)
        if(getcolo(k, j)) flip[k + 1][j] = 1;
    return dfs(k + 1);
}

void solve()
{
    int i, j, maxcase = 1 << n, ret = inf, num, tem;
    for(i = 0; i < maxcase; ++i)
    {
        memset(flip, 0, sizeof(flip));
        for(j = n - 1, tem = i; j >= 0; --j, tem >>= 1)
            flip[0][j] = tem & 1;
        num = dfs(0);
        if(num != -1 && num < ret)
        {
            ret = num;
            memcpy(opt, flip, sizeof(flip));
        }
    }

    if(ret == inf) cout << "IMPOSSIBLE" << endl;
    else
    {
        for(i = 0; i < m; ++i)
            for(j = 0; j < n; ++j)
                if(j == n -1) cout << opt[i][j] << endl;
                else cout << opt[i][j] << " ";
    }
}
int main()
{
    while(~scanf("%d%d",&m,&n))
    {
        getmap();
        solve();
    }
    return 0;
}


E - Find The Multiple

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
int flag;
void dfs(unsigned long long t, int n, int k)
{
    if(flag) return ; //已发现答案 退出
    if(t % n == 0)
    {                 //输出答案并标记
        cout << t << endl;
        flag = 1;
        return ;
    }
    if(k == 19) return ;  //到第19层,回溯
    dfs(t*10, n, k+1);    //搜索t*10
    dfs(t*10+1, n, k+1);  //搜索t*10+1
}
int main()
{
    int n;
    while(~scanf("%d",&n) && n)
    {
        flag = 0;
        dfs(1, n, 0);
    }
    return 0;
}

F - Prime Path

AC代码:      

//要选G++,C++会CE(我也不知道为什么

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
const int Max = 10010;
int m, n;
struct node
{
    int x;
    int sum;
};
int pri[Max];
int vis[Max];
int bfs()
{
    memset(vis, 0, sizeof(vis));
    node now, nex;
    now.x = n;
    now.sum = 0;
    queue<node> q;
    vis[n] = 1;
    q.push(now);
    while(!q.empty())
    {
        now = q.front();
        q.pop();
        if(now.x == m)  return now.sum;
        for(int i = 0; i < 10; ++i)   //换个位
        {
            nex.x = now.x/10*10+i;
            nex.sum = now.sum + 1;
            if(!vis[nex.x] && !pri[nex.x])//未访问过此数并且这是个素数
            {
                vis[nex.x] = 1;
                q.push(nex);
            }
        }
        for(int i = 0; i < 10; ++i)  //换十位
        {
            int tem = now.x % 10;
            nex.x = now.x/100*100+(10*i)+tem;
            nex.sum = now.sum + 1;
            if(!vis[nex.x] && !pri[nex.x])
            {
                vis[nex.x] = 1;
                q.push(nex);
            }
        }
        for(int i = 0; i < 10; ++i)   //换百位
        {
            int tem = now.x % 100;
            nex.x = now.x/1000*1000+(100*i)+tem;
            nex.sum = now.sum + 1;
            if(!vis[nex.x] && !pri[nex.x])
            {
                vis[nex.x] = 1;
                q.push(nex);
            }
        }
        for(int i = 1; i < 10; ++i)  //换千位,要从1开始哦
        {
            nex.x = now.x%1000 + i*1000;
            nex.sum = now.sum + 1;
            if(!vis[nex.x] && !pri[nex.x])
            {
                vis[nex.x] = 1;
                q.push(nex);
            }
        }
    }
    return 0;
}
int main()
{
    int t;
    memset(pri, 0, sizeof(pri));
    pri[1] = 1;
    pri[0] = 1;
    m=sqrt(Max)+1;
    for(int i = 2; i < m; i++)
    {
        if(!pri[i])
        {
            for(int j=i*i;j<=Max;j+=i)
            {
                pri[j]=1;
            }
        }
    }
    while(~scanf("%d",&t))
    {
        while(t--)
        {
            scanf("%d%d",&m,&n);
            printf("%d\n",bfs());
        }
    }
    return 0;
}


G - Shuffle'm Up

AC代码:

//这是一道模拟题吧,放错位置了或者也可以用搜索做

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <map>
using namespace std;
string s1, s2, s, ans;
int main()
{
    int t, flag, num, n;
    while(~scanf("%d",&t))
    {
        for(int cou = 1; cou <= t; ++cou)
        {
            num = 0;
            map<string, int> tem;
            scanf("%d",&n);
            int j = 0;
            cin >> s1 >> s2 >> ans;
            while(1)
            {
                num++;
                s.clear();
                for(int i = 0; i < n; ++i)
                {
                    s += s2[i];
                    s += s1[i];
                }
                if(s == ans)
                {
                    flag = 1;
                    break;
                }
                else
                {
                    if(tem[s])
                    {
                        flag = 0;
                        break;
                    }
                    tem[s] = 1;
                }
                s1 = s2 = "";
                for(int i = 0; i < n; ++i)
                    s1 += s[i];
                for(int i = n; i < 2*n; ++i)
                    s2 += s[i];
            }
            if(flag)
                cout << cou << " " << num << endl;
            else
                cout << cou << " -1" << endl;
        }
    }
    return 0;
}

H - Pots

AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
const int inf = 0x3f3f3f3f;
int a, b, c;
int flag, res;
int vis[105][105];
char pa[10010], pp[10010];
void dfs(int x, int y, int dep)
{
    if(dep > res) return ;
    if(x == c || y == c)  //找到目标
    {
        if(dep < res)
        {
            flag = 1;
            res = dep;
            for(int i = 0; i < res; ++i)
                pa[i] = pp[i];
        }
        return ;
    }
    if(x < a && !vis[a][y])//FILL 1
	{
		vis[a][y] = 1;
		pp[dep] = 'f';
		dfs(a, y, dep+1);
		vis[a][y] = 0;
	}
	if(y < b && !vis[x][b])//FILL 2
	{
		vis[x][b] = 1;
		pp[dep] = 'F';
		dfs(x, b, dep+1);
		vis[x][b] = 0;
	}
	if(x > 0 && !vis[0][y])//DROP 1
	{
		vis[0][y] = 1;
		pp[dep] = 'd';
		dfs(0, y, dep+1);
		vis[0][y] = 0;
	}
	if(y > 0 && !vis[x][0])//DROP 2
	{
		vis[x][0] = 1;
		pp[dep] = 'D';
		dfs(x, 0, dep+1);
		vis[x][0] = 0;
	}
	if(x > 0 && y < b)//POUR(1,2)
	{
		int t = min(x, b-y);
		if(!vis[x-t][y+t])
		{
			vis[x-t][y+t] = 1;
			pp[dep] = 'p';
			dfs(x-t, y+t, dep+1);
			vis[x-t][y+t] = 0;
		}
	}
	if(y > 0 && x < a)//POUR(2,1)
	{
		int t = min(y, a-x);
		if(!vis[x+t][y-t])
		{
			vis[x+t][y-t] = 1;
			pp[dep] = 'P';
			dfs(x+t, y-t, dep+1);
			vis[x+t][y-t] = 0;
		}
	}
	return ;
}
int main()
{
    while(~scanf("%d%d%d",&a,&b,&c) && (a||b||c))
    {
        memset(vis, 0, sizeof(vis));
        vis[0][0] = 1;
        flag = 0;
        res = inf;
        dfs(0, 0, 0);
        if(flag)
        {
            cout << res << endl;
            for(int i = 0; i < res; ++i)
            {
                if(pa[i] == 'f')
                    cout << "FILL(1)" << endl;
                else if(pa[i] == 'F')
                    cout << "FILL(2)" << endl;
                else if(pa[i] == 'd')
                    cout << "DROP(1)" << endl;
                else if(pa[i] == 'D')
                    cout << "DROP(2)" << endl;
                else if(pa[i] == 'p')
                    cout << "POUR(1,2)" << endl;
                else if(pa[i] == 'P')
                    cout << "POUR(2,1)" << endl;
            }
        }
        else cout << "impossible" << endl;
    }
    return 0;
}

I - Fire Game

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
using namespace std;
const int inf = 0x3f3f3f3f;
int n, m, tmin, tmax;
int mapa[15][15], vis[15][15];
int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0} };
int visit[15][15][15][15];
struct state
{
    int x, y;
    int t;
};
void bfs(int x1, int y1, int x2,int y2)
{

    queue<state> s;
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
            vis[i][j] = mapa[i][j];

    state p;
    p.x = x1; p.y = y1; p.t = 0; s.push(p);
    p.x = x2; p.y = y2; p.t = 0; s.push(p);
    vis[x1][y1] = vis[x2][y2] = 0;

    while(!s.empty())
    {
        state q;
        q = s.front();
        s.pop();
        tmax = q.t;
        for(int i = 0; i < 4; ++i)
        {
            state tem;
            tem.x = q.x + dir[i][0];
            tem.y = q.y + dir[i][1];
            tem.t = q.t + 1;
            if(tem.x < 1 || tem.x > n || tem.y < 1 || tem.y > m) continue;
            if(!vis[tem.x][tem.y]) continue;
            vis[tem.x][tem.y] = 0;
            s.push(tem);

        }
    }

    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j)
            if(vis[i][j]) tmax = inf;
}
int main()
{
    int t, cou;
    char c;
    while(~scanf("%d",&t))
    {
        for(cou = 1; cou <= t; ++cou)
        {
            scanf("%d%d",&n, &m);
            getchar();
            for(int i = 1; i <= n; ++i)
            {
                for(int j = 1; j <= m; ++j)
                {
                    cin >> c;
                    if(c == '#')  mapa[i][j] = 1;
                    else mapa[i][j] = 0;
                }
            }
            tmin = inf;
            memset(visit, 0, sizeof(visit));
            for(int i = 1; i <= n; ++i)
                for(int j = 1; j <= m; ++j)
                    for(int p = 1; p <= n; ++p)
                        for(int q = 1; q <= m; ++q)
                        {
                            if(mapa[i][j] && mapa[p][q] && !visit[i][j][p][q])
                            {
                                visit[i][j][p][q] = 1;
                                bfs(i, j, p, q);
                                tmin = min(tmin, tmax);
                            }
                        }
            if(tmin == inf)
                printf("Case %d: -1\n",cou);
            else
                printf("Case %d: %d\n",cou, tmin);
        }
    }
    return 0;
}

J - Fire!

AC代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
int n, m;
char mapa[1005][1005];
int fir[1005][1005];
int vis[1005][1005];
int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1} };
struct node
{
    int x, y;
};
queue<node> q1;
queue<node> q2;

void Fbfs()
{
    node now;
    while(!q1.empty())
    {
        now = q1.front();
        q1.pop();
        for(int i = 0; i < 4; ++i)
        {
            int xx = now.x + dir[i][0];
            int yy = now.y + dir[i][1];
            if(xx > n || xx < 1 || yy < 1 || yy > m) continue;
            if(mapa[xx][yy] == '#' || mapa[xx][yy] == 'F') continue;
            if(fir[xx][yy] != -1) continue;
            node tem;
            fir[xx][yy] = fir[now.x][now.y] + 1;
            tem.x = xx;
            tem.y = yy;
            q1.push(tem);
        }
    }
}

void Jbfs()
{
    node now;
    while(!q2.empty())
    {
        now = q2.front();
        q2.pop();
        if(now.x == 1 || now.x == n || now.y == 1 || now.y == m)
        {
            cout << vis[now.x][now.y]+1 << endl;
            return ;
        }
        for(int i = 0; i < 4; ++i)
        {
            int xx = now.x + dir[i][0];
            int yy = now.y + dir[i][1];
            if(xx > n || xx < 1 || yy < 1 || yy > m) continue;
            if(mapa[xx][yy] == '#' || mapa[xx][yy] == 'F' || mapa[xx][yy] == 'J') continue;
            if(vis[xx][yy] != -1) continue;
            if(fir[xx][yy] == -1 || (vis[now.x][now.y] < fir[xx][yy] - 1))
            {
                node tem;
                vis[xx][yy] = vis[now.x][now.y] + 1;
                tem.x = xx;
                tem.y = yy;
                q2.push(tem);
            }
        }
    }
    cout << "IMPOSSIBLE" << endl;
}
int main()
{
    int t;
    while(~scanf("%d",&t))
    {
        while(t--)
        {
            scanf("%d%d",&n,&m);
            node peop, fire;
            memset(vis, -1, sizeof(vis));
            memset(fir, -1, sizeof(fir));
            while(!q1.empty())  q1.pop();
            while(!q2.empty())  q2.pop();
            for(int i = 1; i <= n; ++i)
                for(int j = 1; j <= m; ++j)
                {
                    cin >> mapa[i][j];
                    if(mapa[i][j] == 'F')
                    {
                        fire.x = i;
                        fire.y = j;
                        q1.push(fire);
                        fir[i][j] = 0;
                    }
                    if(mapa[i][j] == 'J')
                    {
                        peop.x = i;
                        peop.y = j;
                        q2.push(peop);
                        vis[i][j] = 0;
                    }
                }
            Fbfs();
            Jbfs();
        }
    }
    return 0;
}


K - 迷宫问题

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[5][5];
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1} };
struct node
{
    int x, y, pre;
}q[100];
int fir = 0,las = 1;

void print(int n)
{
    if(q[n].pre != -1)
    {
        print(q[n].pre);
        printf("(%d, %d)\n",q[n].x, q[n].y);
    }
}

void bfs(int x, int y)
{
    q[fir].pre = -1;
    q[fir].x = x;
    q[fir].y = y;
    int xx, yy;
    while(fir < las)
    {
        for(int i = 0; i < 4; ++i)
        {
            xx = q[fir].x + dir[i][0];
            yy = q[fir].y + dir[i][1];
            if(xx < 0 || yy < 0 || xx >= 5 || yy >= 5 || a[xx][yy]) continue;

            a[xx][yy] = 1;
            q[las].pre = fir;
            q[las].x = xx;
            q[las].y = yy;
            las++;

            if(xx == 4 && yy == 4) print(fir);
        }
        fir++;
    }
}
int main()
{
    for(int i = 0; i < 5; ++i)
        for(int j = 0; j < 5; ++j)
        cin >> a[i][j];
    printf("(0, 0)\n");
    bfs(0, 0);
    printf("(4, 4)\n");
    return 0;
}

L - Oil Deposits

AC代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 105;
char pic[maxn][maxn];
int m, n, idx[maxn][maxn];

void dfs(int r, int c, int id)
{
    if(r < 0 || r >= m || c < 0 || c >= n) return ;//越界
    if(idx[r][c] > 0 || pic[r][c] != '@') return ;//非'@'格子或已访问过格子
    idx[r][c] = id;
    for(int dr = -1; dr <= 1; ++dr)
        for(int dc = -1; dc <= 1; ++dc)
        if(dr != 0 || dc != 0) dfs(r+dr, c+dc, id);
}

int main()
{
    while(~scanf("%d%d",&m,&n))
    {
        if(n == 0 && m == 0) break;
        for(int i = 0; i < m; ++i) scanf("%s",pic[i]);
        memset(idx, 0, sizeof(idx));
        int cnt = 0;
        for(int i = 0; i < m; ++i)
            for(int j = 0; j < n; ++j)
            if(idx[i][j] == 0 && pic[i][j] == '@') dfs(i, j, ++cnt);
            cout << cnt << endl;
    }
    return 0;
}


M - 非常可乐

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
using namespace std;
int rq[3]; //容器的容量
int vis[105][105][105];
struct qingkuang
{
    int num[3];
    int out;
} now, nex;

void bfs(int ss, int n, int m)
{
    memset(vis, 0, sizeof(vis));
    queue<qingkuang> s;
    now.num[0] = ss;
    now.num[1] = n;
    now.num[2] = m;
    vis[ss][n][m] = 1;
    now.out = 0;
    s.push(now);
    while(!s.empty())
    {
        now = s.front();
        s.pop();
        for(int i = 0; i < 2; ++i)   //是否满足情况(共三种,这里有种判断了2次,还可以优化一下)
            for(int j = 0; j < 3; ++j)
            {
                if(i == j) continue;
                if(now.num[i] == now.num[j] && now.num[3-i-j] == 0)
                {
                    cout << now.out << endl;
                    return ;
                }
            }

//所有倒的方法一共就6种,分别为1->2,1->3,2->1,2->3,3->1,3->2
//开始模拟倒可乐的过程
        for(int i = 0; i < 3; ++i)
        {
            for(int j = 0; j < 3; ++j)
            {
                if(i == j) continue;
                if(now.num[i] + now.num[j] <= rq[j])   //i全部倒入j中
                {
                    nex.num[j] = now.num[j] + now.num[i];
                    nex.num[i] = 0;
                }
                else          //j被倒满
                {
                    nex.num[i] = now.num[i] - (rq[j] - now.num[j]);
                    nex.num[j] = rq[j];
                }
                for(int k = 0; k < 3; ++k)  //维护一下当前步骤
                {
                    if(k == i || k == j) continue;
                    nex.num[k] = now.num[k];
                }
                nex.out = now.out + 1;
                if(vis[nex.num[0]][nex.num[1]][nex.num[2]] == 0)
                {
                    vis[nex.num[0]][nex.num[1]][nex.num[2]] = 1;
                    s.push(nex);
                }
            }
        }
    }
    cout << "NO" << endl;
    return ;
}

int main()
{
    int s, n, m;
    while(~scanf("%d%d%d",&s, &n, &m) && (s || n || m))
    {
        rq[0] = s;
        rq[1] = n;
        rq[2] = m;
        bfs(s, 0, 0);
    }
    return 0;
}


N - Find a way

AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int inf = 0x3f3f3f3f;
char mapa[205][205];
int vis[205][205];
int dis[2][205][205];
int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1} };
int n, m;
int startx, starty;
int endx, endy;
struct node
{
    int x, y;
    int sum;
};

void bfs(int idx, int x, int y)
{
    memset(vis, 0, sizeof(vis));
    vis[x][y] = 1;
    queue<node> q;
    node now, nex;
    now.x = x;
    now.y = y;
    now.sum = 0;
    q.push(now);
    while(!q.empty())
    {
        now = q.front();
        q.pop();
        if(mapa[now.x][now.y] == '@')
            dis[idx][now.x][now.y] = now.sum;
        for(int i = 0; i < 4; ++i)
        {
            nex.x = now.x + dir[i][0];
            nex.y = now.y + dir[i][1];
            if(nex.x < 0 || nex.x >= n || nex.y < 0 || nex.y >= m)  continue; //越界
            if(vis[nex.x][nex.y])  continue;
            if(mapa[nex.x][nex.y] == '#') continue;
            vis[nex.x][nex.y] = 1;
            nex.sum = now.sum + 1;
            q.push(nex);
        }
    }
}

int main()
{

    while(~scanf("%d%d",&n,&m))
    {
        memset(mapa, 0, sizeof(mapa));
        memset(dis, inf, sizeof(dis));   //初始化为无穷远
        for(int i = 0; i < n; ++i)
            scanf("%s",mapa[i]);

        for(int i = 0; i < n; ++i)
            for(int j = 0; j < m; ++j)
            {
                if(mapa[i][j] == 'Y')
                {
                    startx = i;
                    starty = j;
                }
                if(mapa[i][j] == 'M')
                {
                    endx = i;
                    endy = j;
                }
            }

        bfs(0, startx, starty);
        bfs(1, endx, endy);
        int ans = inf;

        /*cout << 233 << endl;
        cout << startx << " " << starty << endl;
        cout << endx << " " << endy << endl;*/

        for(int i = 0; i < n; ++i)
            for(int j = 0; j < m; ++j)
                if(mapa[i][j] == '@')
                    ans = min(ans, dis[0][i][j] + dis[1][i][j]);

        cout << ans*11 << endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值