1. 程式人生 > >[kuangbin帶你飛]專題一 簡單搜尋 題解

[kuangbin帶你飛]專題一 簡單搜尋 題解

時間很緊了,馬上就要大三了。。 卻還在低階演算法遨遊,說來真是懺愧,好好刷題了,兩個寒假全浪費了

看到了一個同是大二,卻比自己厲害很多的同齡人,自己需要加把勁了

加油!



A題 棋盤問題

直接dfs,列舉所有情況就行

程式碼如下

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
char a[10][10];
int ans=0;
int n,k;
int visit [10];
void bfs(int cnt,int x,int y)
{
    if(cnt==k) {
        ans++;
        return ;
    }
    visit[y]=1;
    for(int i=x+1;i<n;i++){
        for(int j=0;j<n;j++){
            if(visit[j]==0&&a[i][j]=='#') {
                bfs(cnt+1,i,j);
            }
        }
    }
    visit[y]=0;
}
int main()
{

    while(~scanf("%d%d",&n,&k)){
        if(n==-1&&k==-1) {
            break;
        }
        for(int i=0;i<n;i++) {
            scanf("%s",a[i]);
        }
        int x,y;
        ans=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(a[i][j]=='#') {
                   memset(visit,0,sizeof(visit));
                    bfs(1,i,j);
                }
            }
        }
        printf("%d\n",ans);
    }
}

B題

三維的bfs

程式碼如下

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
char a[35][35][35];
int l,r,c;
struct Node
{
    int x,y,z;
}s,e;
int xyz[6][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};
void bfs()
{
    int visit[35][35][35];
    memset(visit,-1,sizeof(visit));
    queue<Node> q;
    q.push(s);
    visit[s.x][s.y][s.z]=0;
    while(!q.empty()) {
        Node temp=q.front();
        q.pop();
        for(int i=0;i<6;i++){
            int xx=temp.x+xyz[i][0];
            int yy=temp.y+xyz[i][1];
            int zz=temp.z+xyz[i][2];
            if(visit[xx][yy][zz]==-1&&(a[xx][yy][zz]=='.'||a[xx][yy][zz]=='E')) {
                Node n;
                n.x=xx; n.y=yy; n.z=zz;
                q.push(n);
                visit[xx][yy][zz]=visit[temp.x][temp.y][temp.z]+1;
            }
        }
        if(visit[e.x][e.y][e.z]!=-1) {
            printf("Escaped in %d minute(s).\n",visit[e.x][e.y][e.z]); return ;
        }
    }
    printf("Trapped!\n");
    return ;
}
int main()
{
    while(~scanf("%d%d%d",&l,&r,&c)) {
        if(l==0&&r==0&&c==0) {
            break;
        }
        for(int i=0;i<l;i++){
            for(int j=0;j<r;j++){
                scanf("%s",a[i][j]);
            }
        }
        for(int i=0;i<l;i++){
            for(int j=0;j<r;j++){
                for(int k=0;k<c;k++){
                    if(a[i][j][k]=='S') {
                        s.x=i; s.y=j; s.z=k;
                    }
                    if(a[i][j][k]=='E') {
                        e.x=i; e.y=j; e.z=k;
                    }
                }
            }
        }
        bfs();

    }
}

C題

最簡單的bfs 入門題

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int visit[100005];
int n,k;
void bfs()
{
   memset(visit,-1,sizeof(visit));
   queue<int> q;
   visit[n]=0;
   q.push(n);
   while(!q.empty()){
        int temp=q.front();
        q.pop();
        if(temp+1<=100000&&visit[temp+1]==-1) {
            q.push(temp+1);
            visit[temp+1]=visit[temp]+1;
        }
        if(temp-1>=0&&visit[temp-1]==-1) {
            q.push(temp-1);
            visit[temp-1]=visit[temp]+1;
        }
        if(2*temp<=100000&&visit[2*temp]==-1) {
            q.push(2*temp);
            visit[2*temp]=visit[temp]+1;
        }
        if(visit[k]!=-1) {
            printf("%d\n",visit[k]); break;
        }
   }
}
int main()
{
    scanf("%d%d",&n,&k);
    bfs();
}

D題 翻轉問題

直接暴力,是2^(n*m) 列舉第一行 n*m*2^n

程式碼如下

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int m,n;
int tile[20][20];
int ans[20][20];
int temp[20][20];
int dx[5]={-1,0,0,0,1};
int dy[5]={0,-1,0,1,0};
int get(int x,int y)
{
    int c=tile[x][y];
    for(int i=0;i<5;i++){
        int xx=x+dx[i],yy=y+dy[i];
        if(0<=xx&&xx<m&&0<=yy&&yy<n) {
            c+=temp[xx][yy];
        }
    }
    return c%2;
}
int cal()
{
    for(int i=1;i<m;i++){
        for(int j=0;j<n;j++){
            if(get(i-1,j)!=0) {
                temp[i][j]=1;
            }
        }
    }
    for(int i=0;i<n;i++){
        if(get(m-1,i)!=0) {
            return -1;
        }
    }
    int res=0;
    for(int i=0;i<m;i++) {
        for(int j=0;j<n;j++)
            res+=temp[i][j];
    }
    return res;
}

int main()
{
    scanf("%d%d",&m,&n);
    for(int i=0;i<m;i++)
        for(int j=0;j<n;j++)
            scanf("%d",&tile[i][j]);
    int res=-1;
    for(int i=0;i<1<<n;i++){
        memset(temp,0,sizeof(temp));
        for(int j=0;j<n;j++){
            temp[0][n-1-j]=i>>j&1;
        }
        int num=cal();
        if(num>=0&&(res<0||res>num)) {
            res=num;
            memcpy(ans,temp,sizeof(temp));
        }
    }
    if(res<0) {
        printf("IMPOSSIBLE\n");
    }
    else{
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
                printf("%d%c",ans[i][j],j+1==n?'\n':' ');
    }
}
E題

bfs

 程式碼如下

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
void bfs(int n)
{
    queue<long long> q;
    q.push(1);
    while(!q.empty()) {
        long long temp=q.front();
        q.pop();
        if(temp%n==0) {
            printf("%lld\n",temp);
            break;
        }
        q.push(temp*10);
        q.push(temp*10+1);
    }
}
int main()
{
    int n;
    while(~scanf("%d",&n)) {
        if(n==0) break;
        bfs(n);
    }
}
F題

打個表,列舉

程式碼如下

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
bool is_prime[10005];
void bfs(int a,int b)
{
    int visit[10005];
    memset(visit,-1,sizeof(visit));
    visit[a]=0;
    queue<int> q;
    q.push(a);
    while(!q.empty()){
        int temp=q.front();
        int s=temp;
        q.pop();
        int num[4],cnt=0;
        while(temp){
            num[cnt++]=temp%10;
            temp/=10;
        }
        for(int i=0;i<=9;i++){
            if(i!=num[0]) {
                temp=num[3]*1000+num[2]*100+num[1]*10+i;
                if(is_prime[temp]&&visit[temp]==-1) {
                    q.push(temp);
                    visit[temp]=visit[s]+1;
                }
            }
        }
        for(int i=0;i<=9;i++){
            if(i!=num[1]) {
                temp=num[3]*1000+num[2]*100+i*10+num[0];
                if(is_prime[temp]&&visit[temp]==-1) {
                    q.push(temp);
                    visit[temp]=visit[s]+1;
                }
            }
        }
        for(int i=0;i<=9;i++){
            if(i!=num[2]) {
                temp=num[3]*1000+i*100+num[1]*10+num[0];
                if(is_prime[temp]&&visit[temp]==-1) {
                    q.push(temp);
                    visit[temp]=visit[s]+1;
                }
            }
        }
        for(int i=1;i<=9;i++){
            if(i!=num[3]) {
                temp=i*1000+num[2]*100+num[1]*10+num[0];
                if(is_prime[temp]&&visit[temp]==-1) {
                    q.push(temp);
                    visit[temp]=visit[s]+1;
                }
            }
        }
        if(visit[b]!=-1) {
            printf("%d\n",visit[b]); break;
        }
    }
}
int main()
{
    for(int i=0;i<=9999;i++)
        is_prime[i]=true;
    for(int i=2;i<=9999;i++){
        if(is_prime[i]) {
            for(int j=2*i;j<=9999;j+=i){
                is_prime[j]=false;
            }
        }
    }
    int t;
    scanf("%d",&t);
    while(t--){
        int a,b;
        scanf("%d%d",&a,&b);
        bfs(a,b);
    }
}

G題

讀懂題就很簡單

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    int num=1;
    while(t--) {
        int len;
        scanf("%d",&len);
        map<string,bool> m;
        string s1,s2,s12;
        cin>>s1>>s2>>s12;
        printf("%d ",num++);
        int cnt=0;
        int flag=-1;
        while(true) {
            cnt++;
            string temp;
            int tt=0;
            while(tt<len) {
                temp+=s2[tt];
                temp+=s1[tt];
                 tt++;
            }
            if(temp==s12) {
                flag=1;
                break;
            }
            if(m[temp]==true) {
                flag=0; break;
            }
            m[temp]=true;
            s1=temp.substr(0,len);
            s2=temp.substr(len);
        }
        if(flag==1) {
            printf("%d\n",cnt);
        }
        else{
            printf("-1\n");
        }
    }
}
H題

bfs,6種狀態,記錄前面的狀態

程式碼如下

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int a,b,c;
int visit[105][105];
struct Node
{
    int A,B,step;
    int pa,pb;
}v[105][105],as;
string s[105];
int bfs()
{
    memset(visit,0,sizeof(visit));
    for(int i=0;i<=100;i++) {
        for(int j=0;j<=100;j++){
            v[i][j].pa=i; v[i][j].pb=j;
        }
    }
    queue<Node> q;
    v[0][0].A=0; v[0][0].B=0; v[0][0].step=0;
    visit[0][0]=1;
    q.push(v[0][0]);
    while(!q.empty()) {
        Node temp=q.front();
        q.pop();
        if(temp.A==c||temp.B==c) {
            as=temp;
            return temp.step;
        }
        if(temp.A!=a&&visit[a][temp.B]==0) {
            v[a][temp.B].A=a; v[a][temp.B].B=temp.B;
            v[a][temp.B].step=temp.step+1;
            v[a][temp.B].pa=temp.A; v[a][temp.B].pb=temp.B;
            visit[a][temp.B]=1;
            q.push(v[a][temp.B]);
        }
        if(temp.B!=b&&visit[temp.A][b]==0) {
            v[temp.A][b].A=temp.A; v[temp.A][b].B=b;
            v[temp.A][b].step=temp.step+1;
            v[temp.A][b].pa=temp.A; v[temp.A][b].pb=temp.B;
            visit[temp.A][b]=1;
            q.push(v[temp.A][b]);
        }
        if(temp.A!=0&&visit[0][temp.B]==0) {
            v[0][temp.B].A=0; v[0][temp.B].B=temp.B;
            v[0][temp.B].step=temp.step+1;
            v[0][temp.B].pa=temp.A;  v[0][temp.B].pb=temp.B;
            visit[0][temp.B]=1;
            q.push(v[0][temp.B]);
        }
        if(temp.B!=0&&visit[temp.A][0]==0) {
            v[temp.A][0].A=temp.A; v[temp.A][0].B=0;
            v[temp.A][0].step=temp.step+1;
            v[temp.A][0].pa=temp.A; v[temp.A][0].pb=temp.B;
            visit[temp.A][0]=1;
            q.push(v[temp.A][0]);
        }
        if((temp.A+temp.B>0&&temp.A+temp.B<=a)&&visit[temp.A+temp.B][0]==0) { //bµ¼Èëa
            v[temp.A+temp.B][0].A=temp.A+temp.B; v[temp.A+temp.B][0].B=0;
            v[temp.A+temp.B][0].step=temp.step+1;
             v[temp.A+temp.B][0].pa=temp.A;  v[temp.A+temp.B][0].pb=temp.B;
            visit[temp.A+temp.B][0]=1;
            q.push(v[temp.A+temp.B][0]);
        }
        if(temp.A+temp.B>a&&visit[a][temp.A+temp.B-a]==0) {              //bµ¼Èëa
           v[a][temp.A+temp.B-a].A=a; v[a][temp.A+temp.B-a].B=temp.A+temp.B-a;
           v[a][temp.A+temp.B-a].step=temp.step+1;
           v[a][temp.A+temp.B-a].pa=temp.A; v[a][temp.A+temp.B-a].pb=temp.B;
           visit[a][temp.A+temp.B-a]=1;
           q.push(v[a][temp.A+temp.B-a]);
        }
        if((temp.A+temp.B>0&&temp.A+temp.B<=b)&&visit[0][temp.A+temp.B]==0) {
            v[0][temp.A+temp.B].A=0; v[0][temp.A+temp.B].B=temp.A+temp.B;
            v[0][temp.A+temp.B].step=temp.step+1;
            v[0][temp.A+temp.B].pa=temp.A; v[0][temp.A+temp.B].pb=temp.B;
            visit[0][temp.A+temp.B]=1;
            q.push(v[0][temp.A+temp.B]);
        }
        if(temp.A+temp.B>b&&visit[temp.A+temp.B-b][b]==0) {
            v[temp.A+temp.B-b][b].A=temp.A+temp.B-b; v[temp.A+temp.B-b][b].B=b;
            v[temp.A+temp.B-b][b].step=temp.step+1;
            v[temp.A+temp.B-b][b].pa=temp.A; v[temp.A+temp.B-b][b].pb=temp.B;
            visit[temp.A+temp.B-b][b]=1;
            q.push(v[temp.A+temp.B-b][b]);
        }
    }
    return -1;
}
int main()
{

    while(~scanf("%d%d%d",&a,&b,&c)) {
        int ans=bfs();
        if(ans==-1) {
            printf("impossible\n");
        }
        else{
            printf("%d\n",ans);
            int k=0;
            while(1) {
                if(as.A==0&as.B==0) {
                    break;
                }
                Node pre=v[as.pa][as.pb];
                if(pre.A==as.A&&pre.B!=as.B) {
                    if(as.B==b) {
                        s[k++]="FILL(2)";
                    }
                    else{
                        s[k++]="DROP(2)";
                    }
                }
                 if(pre.A!=as.A&&pre.B==as.B) {
                    if(as.A==a) {
                        s[k++]="FILL(1)";
                    }
                    else{
                        s[k++]="DROP(1)";
                    }
                }
                if(pre.A+pre.B==as.A+as.B) {
                    if(as.A>=pre.A) {
                        s[k++]="POUR(2,1)";
                    }
                    else{
                        s[k++]="POUR(1,2)";
                    }
                }
                as=pre;
            }
            for(int i=k-1;i>=0;i--) {
                cout<<s[i]<<endl;
            }
        }
    }

}
i題 任取兩個點,求最短時間
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int n,m;
 queue<pair<int,int> >q;
char s[15][15];
int visit[15][15];
int cnt=0;
int xy[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int bfs()
{
    int tem=0;
    int ans=0;
    while(!q.empty()) {
        pair<int,int> temp=q.front();
        q.pop();
        tem++;
        for(int i=0;i<4;i++) {
            int dx=temp.first+xy[i][0];
            int dy=temp.second+xy[i][1];
            if(0<=dx&&dx<n&&0<=dy&&dy<m&&visit[dx][dy]==-1&&s[dx][dy]=='#') {
                visit[dx][dy]=visit[temp.first][temp.second]+1;
                q.push(make_pair(dx,dy));
                ans=max(visit[dx][dy],ans);
            }
        }
    }
    if(tem==cnt) {
        return ans;
    }
    else{
        return 1e9;
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    int Case=0;
    while(t--) {
        Case++;
        cnt=0;
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++){
            scanf("%s",s[i]);
            for(int j=0;j<m;j++) {
                if(s[i][j]=='#') {
                    cnt++;
                }
            }
        }
        int ans=1e9;
        for(int i=0;i<n;i++) {
            for(int j=0;j<m;j++) {
                if(s[i][j]=='#') {
                    for(int k=0;k<n;k++) {
                        for(int l=0;l<m;l++) {
                            if(s[k][l]=='#') {
                                 while(!q.empty()) {
                                    q.pop();
                                }
                                q.push(make_pair(i,j));
                                if(i!=k||j!=l) {
                                    q.push(make_pair(k,l));
                                }
                                memset(visit,-1,sizeof(visit));
                                visit[i][j]=0; visit[k][l]=0;
                                ans=min(ans,bfs());
                            }
                        }
                    }
                }
            }
        }
        printf("Case %d: ",Case);
        if(ans==1e9) {
            printf("-1\n");
        }
        else{
            printf("%d\n",ans);
        }
    }

}
j題

先對fire進行bfs,再對f進行bfs

程式碼如下

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int n,m;
char s[1005][1005];
int xy[4][2]={{1,0},{0,-1},{-1,0},{0,1}};
int visit1[1005][1005],visit2[1005][1005];
queue<pair<int,int> > q;
void bfs_fire()
{
    while(!q.empty()) {
        pair<int,int> temp=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int dx=xy[i][0]+temp.first;
            int dy=xy[i][1]+temp.second;
            if(0<=dx&&dx<n&&0<=dy&&dy<m&&visit1[dx][dy]==-1&&s[dx][dy]!='#') {
                q.push(make_pair(dx,dy));
                visit1[dx][dy]=visit1[temp.first][temp.second]+1;
            }
         }
    }
}
int bfs_j(int sx,int sy)
{
    q.push(make_pair(sx,sy));
    visit2[sx][sy]=0;
    while(!q.empty()) {
        pair<int,int> temp=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int dx=xy[i][0]+temp.first;
            int dy=xy[i][1]+temp.second;
            int dev=visit2[temp.first][temp.second]+1;
            if(dx<0||dx>=n||dy<0||dy>=m) {
                return dev;
            }
            if(0<=dx&&dx<n&&0<=dy&dy<m&&s[dx][dy]=='.'&&visit2[dx][dy]==-1&&(visit1[dx][dy]==-1||dev<visit1[dx][dy])) {
                q.push(make_pair(dx,dy));
                visit2[dx][dy]=dev;
            }
         }
    }
    return -1;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
            scanf("%s",s[i]);
        memset(visit1,-1,sizeof(visit1));
        memset(visit2,-1,sizeof(visit2));
        while(!q.empty()) {
            q.pop();
        }
        int jx,jy;
        for(int i=0;i<n;i++) {
            for(int j=0;j<m;j++) {
                if(s[i][j]=='F') {
                    q.push(make_pair(i,j));
                    visit1[i][j]=0;
                }
                if(s[i][j]=='J') {
                    jx=i; jy=j;
                }
            }
        }
        bfs_fire();
        int flag=bfs_j(jx,jy);
        if(flag==-1) {
            printf("IMPOSSIBLE\n");
        }
        else{
            printf("%d\n",flag);
        }

    }
}

k題 水題

程式碼如下

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int a[10][10];
int visit[10][10];
int xy[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
typedef pair<int,int> p;
void bfs( )
{
    queue<p> q;
    memset(visit,-1,sizeof(visit));
    q.push(make_pair(0,0));
    visit[0][0]=0;
    while(!q.empty()) {
        p temp=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int dx=temp.first+xy[i][0];
            int dy=temp.second+xy[i][1];
            if(0<=dx&&dx<5&&0<=dy&&dy<5&&visit[dx][dy]==-1&&a[dx][dy]==0) {
                q.push(make_pair(dx,dy));
                visit[dx][dy]=visit[temp.first][temp.second]+1;
            }
        }
        if(visit[4][4]!=-1) {
            break;
        }
    }
    p a[100];int num=0;
    a[num].first=4; a[num].second=4; num++;
    int x=4,y=4;
    while(true) {
        for(int i=0;i<4;i++){
            int dx=x+xy[i][0];
            int dy=y+xy[i][1];
            if(visit[x][y]-visit[dx][dy]==1) {
                a[num].first=dx; a[num].second=dy; num++;
                x=dx; y=dy; break;
            }
        }
        if(x==0&&y==0) {
            break;
        }
    }
    for(int i=num-1;i>=0;i--){
        printf("(%d, %d)\n",a[i].first,a[i].second);
    }
}
int main()
{
    for(int i=0;i<5;i++)
        for(int j=0;j<5;j++)
            scanf("%d",&a[i][j]);
    bfs();
}
L題

求聯通塊 bfs

程式碼如下

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
char s[105][105];
int n,m;
int xy[8][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
void dfs(int x,int y)
{
    s[x][y]='*';
    for(int i=0;i<8;i++){
        int dx=x+xy[i][0];
        int dy=y+xy[i][1];
        if(0<=dx&&dx<n&&0<=dy&&dy<m&&s[dx][dy]=='@') {
            dfs(dx,dy);
        }
    }
    return ;
}
int main()
{

    while(~scanf("%d%d",&n,&m)) {
        if(n==0&&m==0) {
            break;
        }
        for(int i=0;i<n;i++)
            scanf("%s",s[i]);
        int ans=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(s[i][j]=='@') {
                    dfs(i,j);
                    ans++;
                }
            }
        }
        printf("%d\n",ans);
    }
}

M題

既可以是數論,也可以列舉6種狀態 看的別人的程式碼,寫的另一個類似的題

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int v[5];
int sign[110][110][100];
struct cup//記錄遍歷中3個水杯容藏可樂情況
{
    int v[5];
    int step;
}temp;

void pour(int a,int b)//倒水函式,把a杯子中的可樂倒到b杯子中
{
    int sum=temp.v[a]+temp.v[b];
    if(sum>=v[b])
        temp.v[b]=v[b];
    else
        temp.v[b]=sum;
    temp.v[a]=sum-temp.v[b];
}

void bfs()
{
    int i,j;
    queue<cup>q;
    cup cnt;
    cnt.v[1]=v[1];
    cnt.v[2]=0;
    cnt.v[3]=0;
    cnt.step=0;
    q.push(cnt);
    memset(sign,0,sizeof(sign));
    sign[v[1]][0][0]=1;
    while(!q.empty())
    {
        cnt=q.front();
        q.pop();
        if(cnt.v[1]==cnt.v[3]&&cnt.v[2]==0)
        {
            printf("%d\n",cnt.step);
            return ;
        }
        for(i=1;i<4;++i)
        {
            for(j=1;j<4;++j)
            {
                if(i!=j)//自己不倒水給自己  
                {
                    temp=cnt;//每個水位情況都要把所有操作列舉一遍,所以都要賦值為原始水位情況  
                    pour(i,j);
                    if(!sign[temp.v[1]][temp.v[2]][temp.v[3]])
                    {
                        temp.step++;
                        q.push(temp);
                        sign[temp.v[1]][temp.v[2]][temp.v[3]]=1;
                    }
                }
            }
        }
    }
    printf("NO\n");
}

int main()
{
    while(scanf("%d%d%d",&v[1],&v[2],&v[3])&&v[1]||v[2]||v[3])
    {
        if(v[2]>v[3])
        {
            int t=v[2];
            v[2]=v[3];
            v[3]=t;
        }
        bfs();
    }
    return 0;
}

n題

求兩個點到一個點的最短距離

程式碼如下

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int n,m;
char s[205][205];
int xy[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
void bfs(int sx,int sy,int visit[][205])
{
    queue<pair<int,int> >q;
    q.push(make_pair(sx,sy));
    visit[sx][sy]=0;
    while(!q.empty()) {
        pair<int,int> temp=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int dx=temp.first+xy[i][0];
            int dy=temp.second+xy[i][1];
            if(0<=dx&&dx<n&&0<=dy&&dy<m&&visit[dx][dy]==-1&&s[dx][dy]!='#') {
                q.push(make_pair(dx,dy));
                visit[dx][dy]=visit[temp.first][temp.second]+1;
            }
        }
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m)) {
        for(int i=0;i<n;i++)
            scanf("%s",s[i]);
        int visit1[205][205],visit2[205][205];
        memset(visit1,-1,sizeof(visit1));
        memset(visit2,-1,sizeof(visit2));
        for(int i=0;i<n;i++) {
            for(int j=0;j<m;j++){
                if(s[i][j]=='Y') {
                    bfs(i,j,visit1);
                }
                if(s[i][j]=='M') {
                    bfs(i,j,visit2);
                }
            }
        }
        int ans=1e9;
        for(int i=0;i<n;i++) {
            for(int j=0;j<m;j++){
                if(s[i][j]=='@'&&visit1[i][j]!=-1&&visit2[i][j]!=-1) { 
// 一直錯在這裡,到不了的情況忘了考慮;
                    ans=min(ans,visit1[i][j]+visit2[i][j]);
                }
            }
        }
        printf("%d\n",ans*11);
    }