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\n",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!\n");
        }
        else{
            printf("Escaped in %d minute(s).\n",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\n");continue;
        }
        mem(vis,0);
        printf("%d\n",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\n",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\n",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\n");
        }
        else{
            printf("%d\n",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)\n");
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)\n",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)\n");
    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)\n",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\n", 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\n",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\n",c++,ans);
    }
    return 0;
}

 

posted @ 2019-11-27 21:13  ouluy  阅读(147)  评论(0编辑  收藏  举报