• 19/11/27 搜索小练


    搜索小练


    记得补题

    就写了ABCFL

    A题(poj1321):做过一次……

     #include<iostream>
     #include<cstdio>
     #include<algorithm>
     #include<cstring>
     #include<queue>
     #include<stack>
     #include<cmath>
     using namespace std;
     #define mem(a,b) memset(a,b,sizeof(a))
     #define inf 0x3f3f3f3f
     #define mod 1000000007
     #define ll long long
     #define rep(i,a,b) for(int i=a;i<=b;i++)
     const int maxn=10;
     char g[maxn][maxn];
     int vis[maxn][maxn],xx[maxn],yy[maxn];
     int n,m,maxx,sum;
     void dfs(int sum,int r)
     {
         if(!sum){
             maxx++;
             return;
         }
         for(int i=r;i<n;i++){
             if(!xx[i] && n>=(sum+i)){
                 for(int j=0;j<n;j++){
                    if(!yy[j]){
                         if(g[i][j]=='#'&& !vis[i][j]){
                            yy[j]=1;xx[i]=1;vis[i][j]=1;
                             dfs(sum-1,r+1);
                             yy[j]=0;xx[i]=0;vis[i][j]=0;
                         }
                     }
                 }
             }
         }
     }
     int main()
     {
         while(~scanf("%d%d",&n,&m)){
             if(n==-1 && m==-1){break;}
             for(int i=0;i<n;i++){
                 scanf("%s",g[i]);
                 xx[i]=0,yy[i]=0;
             }
             mem(vis,0);
             maxx=0;
             dfs(m,0);
             printf("%d
    ",maxx);
         }
         return 0;
    }
    

    B题(poj2251):

    题面:找有没有S到E的最短路程,如果没有就输出Trapped!

    思路:直接bfs

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn=110;
    char mp[35][35][35];
    int vis[35][35][35],n,m,l;
    int sx,sy,sc,ex,ey,ec,ans;
    int bu[6]={0,0,0,0,1,-1},bu1[6]={0,0,1,-1,0,0},bu2[6]={1,-1,0,0,0,0};
    struct node{
        int x,y,c,temp;
        node(){}
        node(int xx,int yy,int cc,int t):x(xx),y(yy),c(cc),temp(t){}
        friend bool operator<(const node a,const node b){
            return a.temp>b.temp;
        }
    };
    int bfs(){
        mem(vis,0);
        priority_queue<node> q;
        q.push(node(sx,sy,sc,0));
        vis[sc][sx][sy]=1;
        while(!q.empty()){
            node tt=q.top();q.pop();
    
            for(int i=0;i<6;i++){
               int cc=tt.c+bu[i],xx=tt.x+bu1[i],yy=tt.y+bu2[i],tem=tt.temp+1; //cout<<cc<<xx<<yy<<endl;
               if(ec==cc && xx==ex && yy==ey){return tem;}
               if(mp[cc][xx][yy]=='#' || vis[cc][xx][yy] || cc<0 || cc>=l || xx<0 || xx>=n || yy<0 || yy>=m){continue;}
               vis[cc][xx][yy]=1;
               q.push(node(xx,yy,cc,tem));
            }
        }
        return -1;
    }
    int main(){
        while(~scanf("%d%d%d",&l,&n,&m)){
            if(n==0 && m==0 && l==0){break;}
            for(int i=0;i<l;i++){
                //getchar();
                for(int j=0;j<n;j++){
                    scanf("%s",mp[i][j]);
                    for(int k=0;k<m;k++){
                        if(mp[i][j][k]=='S'){sc=i,sx=j,sy=k;}
                        if(mp[i][j][k]=='E'){ec=i,ex=j,ey=k;}
                    }
                }
                //getchar();
            }
    
            ans=bfs();
            if(ans==-1){
                printf("Trapped!
    ");
            }
            else{
                printf("Escaped in %d minute(s).
    ",ans);
            }
        }
        return 0;
    }

    C题(poj3278):

    题面:有三种操作1. 加一 2 .减一 3 .乘2,一个数字最少需要几步能够另外一个数字(0~1e5)

    思路:直接bfs

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn=1e5+10;
    int vis[maxn],n,m,c;
    struct node{
        int x,y;
        node(){}
        node(int xx,int yy):x(xx),y(yy){}
        friend bool operator<(const node a,const node b){
            return a.y>b.y;
        }
    };
    int bfs(){
       priority_queue<node> q;
       q.push(node(n,0));
       vis[n]=1;
       while(!q.empty()){
            node k=q.top();q.pop();
            int x1=k.x-1,x2=k.x+1,x3=k.x*2,tt=k.y+1;
            if(x1==m){return tt;}
            if(x2==m){return tt;}
            if(x3==m){return tt;}
            if(x1>=0 && x1<=100000 && !vis[x1]){
                vis[x1]=1;q.push(node(x1,tt));
            }
            if(x2>=0 && x2<=100000 && !vis[x2]){
                vis[x2]=1;q.push(node(x2,tt));
            }
            if(x3>=0 && x3<=100000 && !vis[x3]){
                vis[x3]=1;q.push(node(x3,tt));
            }
       }
    }
    int main(){
        while(~scanf("%d%d",&n,&m)){
            if(n==m){
                printf("0
    ");continue;
            }
            mem(vis,0);
            printf("%d
    ",bfs());
        }
        return 0;
    }

    F题(poj3126):

    题面:给T组,每组给两个4位数的素数(无前导零),一个素数变换成另一个素数,是按位进行的,比如1033》》1733算一步,求最少需要几次操作

    思路:因为只有4位,直接预处理,用链式前向星链接,bfs直接找

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn=1e5+10;
    int mp[maxn]={0},n,m,head[maxn],cnt,vis[maxn];
    struct edge{
        int n,next;
        edge(){}
        edge(int nn,int t):n(nn),next(t){}
    }a[maxn<<1];
    struct node{
        int x,t;
        node(){}
        node(int xx,int yy):x(xx),t(yy){}
        friend bool operator<(const node a,const node b){
            return a.t>b.t;
        }
    };
    void upda(int x,int y){
        a[cnt]=edge(y,head[x]);
        head[x]=cnt++;
    }
    bool pan(int x){
        //int xx=(int)sqrt(x);
        for(int i=2;i*i<=x;i++){
            if(x%i==0){return false;}
        }
        return true;
    }
    void chuli(int x){
        int k=x%10,kk=x/10;
        for(int i=1;i<=k;i++){
            if(mp[x-i]){upda(x,x-i);}
        }
        for(int i=1;i<10-k;i++){
            if(mp[x+i]){upda(x,x+i);}
        }
        k=kk%10,kk/=10;
        for(int i=1;i<=k;i++){
            if(mp[x-i*10]){upda(x,x-i*10);}
        }
        for(int i=1;i<10-k;i++){
            if(mp[x+i*10]){upda(x,x+i*10);}
        }
         k=kk%10,kk/=10;
        for(int i=1;i<=k;i++){
            if(mp[x-i*100]){upda(x,x-i*100);}
        }
        for(int i=1;i<10-k;i++){
            if(mp[x+i*100]){upda(x,x+i*100);}
        }
        k=kk%10;
        for(int i=1;i<=k;i++){
            if(mp[x-i*1000]){upda(x,x-i*1000);}
        }
        for(int i=1;i<10-k;i++){
            if(mp[x+i*1000]){upda(x,x+i*1000);}
        }
    }
    int bfs()
    {
        mem(vis,0);
        priority_queue<node> q;
        q.push(node(n,0));vis[n]=1;
        while(!q.empty()){
            node tt=q.top();q.pop();
            if(tt.x==m){
                return tt.t;
            }
            for(int i=head[tt.x];i!=-1;i=a[i].next){
                if(!vis[a[i].n]){
                    vis[a[i].n]=1;q.push(node(a[i].n,tt.t+1));
                }
            }
        }
        return -1;
    }
    int main(){
        cnt=0;mem(head,-1);
        for(int i=1000;i<10000;i++){
            if(pan(i)){
                mp[i]=1;
            }
        }
        for(int i=1000;i<10000;i++){
            if(mp[i]){
                chuli(i);
            }
        }
        int t;
        while(~scanf("%d",&t)){
            for(int i=0;i<t;i++){
                scanf("%d%d",&n,&m);
                printf("%d
    ",bfs());
            }
        }
        return 0;
    }

    L题(hdu1495)

    题面:给了两个杯子的大小,和可乐的量,问能不能平分,如果能平分,要多少次操作

    思路:bfs+倒水问题,看了大佬写法居然是规律题,数论不有点理解不了

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn=1e5+10;
    struct node{
        int a,b,s,t;
        node(){}
        node(int aa,int bb,int ss,int tt):a(aa),b(bb),s(ss),t(tt){}
    }cole[110];
    int a,b,s;
    int vis[110][110];
    int bfs()
    {
        queue<node> q;
        memset(vis,0,sizeof(vis));
        q.push(node(0,0,s,0));
        vis[a][b]=1;
        while(!q.empty())
        {
            node u=q.front(),v;
            if(u.a==s/2 && u.s==s/2)
                return u.t;
            if(u.s && u.a!=a){
                int c=a-u.a;
                if(u.s>=c) v.a=a,v.s=u.s-c;
                else v.a=u.a+u.s,v.s=0;
                v.b=u.b; v.t=u.t+1;
                if(!vis[v.a][v.b]){
                    q.push(v);
                    vis[v.a][v.b]=1;
                }
            }
            if(u.s && u.b!=b){
                int c=b-u.b;
                if(u.s>=c) v.b=b,v.s=u.s-c;
                else v.b=u.b+u.s,v.s=0;
                v.a=u.a; v.t=u.t+1;
                if(!vis[v.a][v.b]){
                    q.push(v);
                    vis[v.a][v.b]=1;
                }
            }
            if(u.a && u.s!=s){
                int c=s-u.s;
                if(u.a>=c) v.s=s,v.a=u.a-c;
                else v.s=u.s+u.a,v.a=0;
                v.b=u.b; v.t=u.t+1;
                if(!vis[v.a][v.b]){
                    q.push(v);
                    vis[v.a][v.b]=1;
                }
            }
            if(u.a && u.b!=b){
                int c=b-u.b;
                if(u.a>=c) v.b=b,v.a=u.a-c;
                else v.b=u.b+u.a,v.a=0;
                v.s=u.s; v.t=u.t+1;
                if(!vis[v.a][v.b]){
                    q.push(v);
                    vis[v.a][v.b]=1;
                }
            }
            if(u.b && u.a!=a){
                int c=a-u.a;
                if(u.b>=c) v.a=a,v.b=u.b-c;
                else v.a=u.a+u.b,v.b=0;
                v.s=u.s; v.t=u.t+1;
                if(!vis[v.a][v.b]){
                    q.push(v);
                    vis[v.a][v.b]=1;
                }
            }
            if(u.b && u.s!=s){
                int c=s-u.s;
                if(u.b>=c) v.s=s,v.b=u.b-c;
                else v.s=u.s+u.b,v.b=0;
                v.a=u.a; v.t=u.t+1;
                if(!vis[v.a][v.b]){
                    q.push(v);
                    vis[v.a][v.b]=1;
                }
            }
            q.pop();
        }
        return 0;
    }
    int main()
    {
        while(scanf("%d%d%d",&s,&a,&b),s||a||b){
            if(s&1){
                puts("NO");continue;
            }
            if(a<b) swap(a,b);
            int ans=bfs();
            if(ans) printf("%d
    ",ans);
            else puts("NO");
        }
        return 0;
    }

    贴一份gcd的写法

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn=1e5+10;
    int gcd(int a, int b)  {
      return b==0?a:gcd(b,a%b);
    }
    int main()
    {
        int a,b,c;
        while(~scanf("%d%d%d",&a,&b,&c)) {
            if(a==0 && b==0 && c==0){break;}
            a/= gcd(b,c);
            if(a&1){
                printf("NO
    ");
            }
            else{
                printf("%d
    ",a-1);
            }
        }
    }

    还剩七道,明天再战

     M题(hdu2612):今天早上(28号)发现居然做过!就是bfs即可,那么我还剩七道

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define inf 0x3f3f3f3f
    #define sscc ios::sync_with_stdio(false);
    using namespace std;
    char mp[205][205];
    struct node{
        int n;
        int m;
        int t;
    };
    int mp2[205][205];
    int bu[4] = { 1, -1, 0, 0 }, bu2[4] = { 0, 0, 1, -1 };
    bool vis[205][205];
    int x, y, n2, m2, mx, my;
    int minn, kk[1005];
    void bfs(int n,int m)
    {
        vis[n][m] = true;
        queue<node>q;
        node sd, ed;
        sd.n = n;
        sd.m = m;
        sd.t = 0;
        q.push(sd);
        while (!q.empty()){
            ed = q.front();
            q.pop();
            if (mp[ed.n][ed.m] == '@' ){
                mp2[ed.n][ed.m] += ed.t;
            }
            for (int i = 0; i < 4; i++){
                sd.n = ed.n + bu[i];
                sd.m = ed.m + bu2[i];
                sd.t = ed.t + 1;
                if (sd.n >= 0 && sd.n < n2 && sd.m < m2 && sd.m >= 0 && !vis[sd.n][sd.m] && mp[sd.n][sd.m]!='#'){
                    vis[sd.n][sd.m] = true;
                    q.push(sd);
                }
            }
        }
    }
    int main()
    {
        sscc;
        while (cin>>n2>>m2){
            memset(mp2, 0, sizeof(mp2));
            memset(vis, false, sizeof(vis));
            int ge = 0;
            minn = inf;
            for (int i = 0; i < n2; i++){
                for (int j = 0; j < m2; j++){
                    cin >> mp[i][j];
                    if (mp[i][j] == 'Y'){
                        x = i; y = j;
                        //cout << x << y << endl;
                    }
                    else if (mp[i][j] == 'M'){
                        mx = i; my = j;
                        //cout << mx << my << endl;
                    }
                    else if (mp[i][j] == '@'){
                        kk[ge++] = i;
                        kk[ge++] = j;
                    }
                }
            }
                bfs(x, y);
                memset(vis, false, sizeof(vis));
                bfs(mx, my);
                for (int i = 0; i < n2; i++){
                    for (int j = 0; j < m2; j++){
                        if (minn > mp2[i][j] && mp2[i][j] != 0){
                            minn = mp2[i][j];
                        }
                    }
                }
            cout << minn * 11 << endl;
        }
        return 0;
    }

     K题(poj3984):是个笨比题,就是存路就行了(7/13)

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<vector>
     8 #include<string>
     9 #define mem(a,b) memset(a,b,sizeof(a))
    10 #define inf 0x3f3f3f3f
    11 using namespace std;
    12 const int maxn=1e5+10;
    13 int a[6][6],vis[6][6]={0};
    14 int bu[4]={0,0,1,-1},bu1[4]={1,-1,0,0};
    15 struct node{
    16     int x,y,t;
    17     string s;
    18     node(){}
    19     node(int xx,int yy,int tt,string ss):x(xx),y(yy),t(tt),s(ss){}
    20     friend bool operator<(const node a,const node b){
    21         return a.t>b.t;
    22     }
    23 };
    24 string bfs()
    25 {
    26     priority_queue<node> q;
    27     q.push(node(0,0,0,""));
    28     vis[0][0]=1;
    29     while(!q.empty()){
    30         node tt=q.top();q.pop();
    31         if(tt.x==4 && tt.y==4){
    32             return tt.s;
    33         }
    34         for(int i=0;i<4;i++){
    35             int xx=tt.x+bu[i],yy=tt.y+bu1[i],t1=tt.t+1;
    36             char b='0'+i;
    37             string bb=tt.s+b;
    38             if(xx>=0 && xx<5 && yy>=0 && yy<5 && !vis[xx][yy] && !a[xx][yy]){
    39                 vis[xx][yy]=1;
    40                 q.push(node(xx,yy,t1,bb));
    41             }
    42         }
    43     }
    44 }
    45 int main(){
    46     for(int i=0;i<5;i++){
    47         for(int j=0;j<5;j++){
    48             scanf("%d",&a[i][j]);
    49         }
    50     }
    51     string c=bfs();
    52     int l=c.size();
    53     printf("(0, 0)
    ");
    54     int sx=0,sy=0;
    55     for(int i=0;i<l;i++){
    56         sx+=bu[c[i]-'0'];sy+=bu1[c[i]-'0'];
    57         printf("(%d, %d)
    ",sx,sy);
    58     }
    59     return 0;
    
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<string>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn=1e5+10;
    int a[6][6],vis[6][6]={0};
    int bu[4]={0,0,1,-1},bu1[4]={1,-1,0,0};
    struct node{
        int x,y,t;
        string s;
        node(){}
        node(int xx,int yy,int tt,string ss):x(xx),y(yy),t(tt),s(ss){}
        friend bool operator<(const node a,const node b){
            return a.t>b.t;
        }
    };
    string bfs()
    {
        priority_queue<node> q;
        q.push(node(0,0,0,""));
        vis[0][0]=1;
        while(!q.empty()){
            node tt=q.top();q.pop();
            if(tt.x==4 && tt.y==4){
                return tt.s;
            }
            for(int i=0;i<4;i++){
                int xx=tt.x+bu[i],yy=tt.y+bu1[i],t1=tt.t+1;
                char b='0'+i;
                string bb=tt.s+b;
                if(xx>=0 && xx<5 && yy>=0 && yy<5 && !vis[xx][yy] && !a[xx][yy]){
                    vis[xx][yy]=1;
                    q.push(node(xx,yy,t1,bb));
                }
            }
        }
    }
    int main(){
        for(int i=0;i<5;i++){
            for(int j=0;j<5;j++){
                scanf("%d",&a[i][j]);
            }
        }
        string c=bfs();
        int l=c.size();
        printf("(0, 0)
    ");
        int sx=0,sy=0;
        for(int i=0;i<l;i++){
            sx+=bu[c[i]-'0'];sy+=bu1[c[i]-'0'];
            printf("(%d, %d)
    ",sx,sy);
        }
        return 0;
    }

    E题(poj1426):一开始以为会爆longlong,想着大数除法又不太会,好难,后来发现根本不会爆,顺手更深的了解了unsigned

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<string>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define inf 0x3f3f3f3f
    #define ll long long
    using namespace std;
    const int maxn=1e5+10;
    int a[6][6],vis[6][6]={0};
    int bu[4]={0,0,1,-1},bu1[4]={1,-1,0,0};
    struct node{
        int x,y,t;
        string s;
        node(){}
        node(int xx,int yy,int tt,string ss):x(xx),y(yy),t(tt),s(ss){}
        friend bool operator<(const node a,const node b){
            return a.t>b.t;
        }
    };
    bool flag;
    void dfs(unsigned ll t, int n, int k){
        if (flag)
            return;
        if (t%n == 0){
            printf("%llu
    ", t);
            flag= true;
            return;
        }
        if (k == 19)
            return;
        dfs(t * 10, n, k + 1);
        dfs(t * 10 + 1, n, k + 1);
    }
    int main()
    {
        int n;
        while (~scanf("%d",&n)){
            if(n==0)break;
            flag = false;
            dfs(1, n, 0);
        }
        return 0;
    }

    I题(poj2150):有两个人烧草堆,如果能烧完输出最少时间,不能就输出-1,因为没有特判只有一个的草堆的情况,所以wa了两次,还pe了一次……

    因为数据小,所以直接暴力了

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<string>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define inf 0x3f3f3f3f
    #define ll long long
    using namespace std;
    const int maxn=1e5+10;
    int vis[15][15],a[400];
    char mp[15][15];
    int n,m,ge;
    int bu[4]={0,0,1,-1},bu1[4]={1,-1,0,0};
    struct node{
        int x,y,t;
        node(){}
        node(int xx,int yy,int tt):x(xx),y(yy),t(tt){}
        friend bool operator<(const node a,const node b){
            return a.t>b.t;
        }
    };
    int bfs(int x1,int y1,int x2,int y2){
        mem(vis,0);int k=2,maxbu=0;//cout<<x1<<y1<<x2<<y2<<endl;
        priority_queue<node>q;
        q.push(node(x1,y1,0));q.push(node(x2,y2,0));
        vis[x1][y1]=vis[x2][y2]=1;
        while(!q.empty()){
            node tt=q.top();q.pop();
            if(k==ge){
                return maxbu;
            }
            for(int i=0;i<4;i++){
                int xx=tt.x+bu[i],yy=tt.y+bu1[i],te=tt.t+1;
                if(xx>=0&&xx<n&&yy>=0&&yy<m&&!vis[xx][yy]&&mp[xx][yy]=='#'){
                    maxbu=max(te,maxbu);
                    k++;vis[xx][yy]=1;q.push(node(xx,yy,te));//cout<<xx<<" "<<k<<" "<<maxbu<<endl;
                     if(k==ge){
                        return maxbu;
                    }
                }
            }
        }
        return -1;
    }
    int main()
    {
        int t,c=1;
        scanf("%d",&t);
        while(t--){
            ge=0;
            int ans=-1;
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++){
                scanf("%s",mp[i]);
            }
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    if(mp[i][j]=='#'){
                        a[ge++]=i*100+j;
                    }
                }
            }
            if(ge==1){
                printf("Case %d: 0
    ",c++);continue;
            }
            //cout<<ge<<endl;
            for(int i=0;i<ge;i++){
                for(int j=i+1;j<ge;j++){
                    int k=bfs(a[i]/100,a[i]%100,a[j]/100,a[j]%100);
                    if(ans==-1 && k!=-1){
                        ans=k;
                    }
                    else if(k!=-1){
                        ans=min(ans,k);
                    }
                }
            }
            printf("Case %d: %d
    ",c++,ans);
        }
        return 0;
    }
  • 相关阅读:
    HDU
    【JZOJ1252】【洛谷P5194】天平【搜索】
    【JZOJ1252】【洛谷P5194】天平【搜索】
    【JZOJ3896】战争游戏【割点】
    【JZOJ3896】战争游戏【割点】
    【JZOJ3895】数字对【ST表】
    【JZOJ3895】数字对【ST表】
    【JZOJ3894】改造二叉树【树】【LIS】
    【JZOJ3894】改造二叉树【树】【LIS】
    【洛谷P4014】【网络流24题】分配问题【费用流】
  • 原文地址:https://www.cnblogs.com/luoyugongxi/p/11945506.html
Copyright © 2020-2023  润新知