• [kuangbin带你飞]专题一 简单搜索


    [kuangbin带你飞]专题一 简单搜索

    算法:sf / /  错误点:w  // 注意细节:xj


    第一题 POJ 1321

    sf:dfs  xj:在于状态函数的标记和取消

      这里输入使用了  ch = getchar() 抓取字符。

      因为要找出所有方法数,所以暴力dfs就可以了。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    int n,k,ck;
    char ch;
    bool h[10],l[10],fk[10][10];
    long long ans;
    
    void init(){
        memset(h,false,sizeof h);
        memset(l,false,sizeof l);
        memset(fk,false,sizeof fk);
        ans=0;ck=0;
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++){
                ch=getchar();
                if(ch=='
    ') ch=getchar();
                if(ch=='#') fk[i][j]=true,ck++;
            }
    }
    
    void dfs(int a,int b,int c){
        if(c==k) ans++;
        else{
            for(int i=a+1;i<n;i++){
                if(h[i]) continue;
                for(int j=0;j<n;j++){
                    if(l[j]) continue;
                    if(fk[i][j]){
                        h[i]=true;l[j]=true;
                        dfs(i,j,c+1);
                        h[i]=false;l[j]=false;
                    }
                }
            }
        }
    }
    
    int main()
    {
        while(cin>>n>>k){
            if(n==-1&&k==-1) break;
            init();
            for(int i=0;i<n&&ck>=k;i++)
                for(int j=0;j<n&&ck>=k;j++)
                    if(fk[i][j]){
                        h[i]=true;l[j]=true;
                        dfs(i,j,1);
                        h[i]=false;l[j]=false;
                        ck--;
                    }
            cout<<ans<<endl;
        }
    
        return 0;
    }
    View Code

    第二题POJ - 2251 

    sf:bfs xj:在于三维的迷宫 用三维状态函数

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    
    using namespace std;
    
    int l,r,c;
    char ch;
    bool fk[31][31][31];
    bool cp;
    
    struct node{
        int z,x,y;
        int cc;
    };
    
    node k,j;
    queue<node> q;
    
    void init(){
        cp=false;
        memset(fk,false,sizeof fk);
        for(int z=1;z<=l;z++)
            for(int x=1;x<=r;x++)
                for(int y=1;y<=c;y++){
                    ch=getchar();
                    while(ch=='
    ') ch=getchar();
                    if(ch=='S') k.cc=0,k.x=x,k.y=y,k.z=z;
                    if(ch=='E') j.x=x,j.y=y,j.z=z;
                    if(ch=='E'||ch=='.') fk[z][x][y]=true;
                }
    }
    
    bool check(int z,int x,int y){
        if(z<1||z>l) return false;
        if(x<1||x>r) return false;
        if(y<1||y>c) return false;
        if(fk[z][x][y]) return true;
        return false;
    }
    
    int main()
    {
        while(cin>>l>>r>>c){
            if(l==0&&r==0&&c==0) break;
            init();
            q.push(k);
            while(!q.empty()){
                node n = q.front();q.pop();
                if(n.x==j.x&&n.z==j.z&&n.y==j.y) {cout<<"Escaped in "<<n.cc<<" minute(s)."<<endl;cp=true;break;}
                if(check(n.z-1,n.x,n.y)) {node m = n;m.z--;m.cc++;q.push(m);fk[n.z-1][n.x][n.y]=false;}
                if(check(n.z+1,n.x,n.y)) {node m = n;m.z++;m.cc++;q.push(m);fk[n.z+1][n.x][n.y]=false;}
                if(check(n.z,n.x-1,n.y)) {node m = n;m.x--;m.cc++;q.push(m);fk[n.z][n.x-1][n.y]=false;}
                if(check(n.z,n.x+1,n.y)) {node m = n;m.x++;m.cc++;q.push(m);fk[n.z][n.x+1][n.y]=false;}
                if(check(n.z,n.x,n.y-1)) {node m = n;m.y--;m.cc++;q.push(m);fk[n.z][n.x][n.y-1]=false;}
                if(check(n.z,n.x,n.y+1)) {node m = n;m.y++;m.cc++;q.push(m);fk[n.z][n.x][n.y+1]=false;}
            }
            while(!q.empty()) q.pop();
            if(!cp) cout<<"Trapped!"<<endl;
        }
        return 0;
    }
    View Code

    POJ - 3278 

    sf:bfs 难点:在于判断  当超过目标不需要 +1

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    
    using namespace std;
    
    const int M = 1e5;
    int n,k;
    int cp[M+5];
    queue<int> q;
    
    int main()
    {
        memset(cp,-1,sizeof cp);
        cin>>n>>k;
        cp[n]=0;
        q.push(n);
        while(!q.empty()){
            int m=q.front();q.pop();
            if(m==k) break;
            if(m*2<=M&&cp[m*2]<0) {q.push(m*2);cp[m*2]=cp[m]+1;}
            if(m+1<=k&&cp[m+1]<0) {q.push(m+1);cp[m+1]=cp[m]+1;}
            if(m>=1&&cp[m-1]<0) {q.push(m-1);cp[m-1]=cp[m]+1;}
        }
        cout << cp[k] << endl;
        return 0;
    }
    View Code

    POJ - 3279 

    sf:暴力枚举第一行的情况(用2进制) 然后每下一行的操作取决于上一行是否存在1

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    #define inf 1e9
    
    long long cnt,tt;
    int n,m;
    char ch;
    int ans[20][20],akb[20][20];
    bool fk[20][20],jk[20][20];
    
    void init(){
        cnt=inf;
        memset(jk,false,sizeof jk);
        for(int i=1;i<=m;i++)
        for(int j=1;j<=n;j++){
            ch=getchar();
            while(ch=='
    '||ch==' ') ch=getchar();
            if(ch=='1') jk[i][j]=true;
        }
    }
    
    void check(int i,int j){
        if(fk[i][j]) fk[i][j]=false;
        else fk[i][j]=true;
        if(fk[i+1][j]) fk[i+1][j]=false;
        else fk[i+1][j]=true;
        if(fk[i+1][j+1]) fk[i+1][j+1]=false;
        else fk[i+1][j+1]=true;
        if(fk[i+1][j-1]) fk[i+1][j-1]=false;
        else fk[i+1][j-1]=true;
        if(fk[i+2][j]) fk[i+2][j]=false;
        else fk[i+2][j]=true;
    }
    
    void check2(int i,int j){
        if(fk[i][j]) fk[i][j]=false;
        else fk[i][j]=true;
        if(fk[i][j+1]) fk[i][j+1]=false;
        else fk[i][j+1]=true;
        if(fk[i][j-1]) fk[i][j-1]=false;
        else fk[i][j-1]=true;
        if(fk[i+1][j]) fk[i+1][j]=false;
        else fk[i+1][j]=true;
    }
    
    bool go(){
        for(int i=1;i<m;i++)
            for(int j=1;j<=n;j++)
                if(fk[i][j]){
                    check(i,j);
                    tt++;if(tt>=cnt) return false;
                    ans[i+1][j]++;
                }
        for(int j=1;j<=n;j++) if(fk[m][j]) return false;
        return true;
    }
    
    void solve(int x){
        tt=0;memset(ans,0,sizeof ans);
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++)
                fk[i][j]=jk[i][j];
        for(int i=0;i<n;i++) if((1<<i)&x) {check2(1,i+1);ans[1][i+1]++;tt++;if(tt>=cnt) return ;}
        if(go()){
            cnt=tt;
            for(int i=1;i<=m;i++)
                for(int j=1;j<=n;j++) akb[i][j]=ans[i][j];
        }
    }
    
    int main()
    {
        cin>>m>>n;
        init();
        for(int i=0;i<(1<<n);i++) solve(i);
        if(cnt==inf) cout<<"IMPOSSIBLE"<<endl;
        else {
            for(int i=1;i<=m;i++){
                for(int j=1;j<=n;j++)
                    cout<<akb[i][j]<<' ';
                cout<<endl;
            }
        }
        return 0;
    }
    View Code

    POJ - 1426 

    sf:bfs  余数*10+0/1  或者 直接dfs

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <queue>
    
    using namespace std;
    
    int n;
    bool fk[201];
    
    struct node{
        int a;
        string str;
    };
    node k;
    
    int main()
    {
        while(cin>>n&&n!=0){
            memset(fk,false,sizeof fk);
            k.a = 1%n;k.str = "1";fk[k.a] = true;
            queue<node> q;q.push(k);
            while(!q.empty()){
                node p = q.front();q.pop();
                int a = p.a;string str = p.str;
                if(a==0) {cout<<str<<endl;break;}
                else{
                    node m;
                    m.a = a*10%n, m.str = str + "0";
                    if(!fk[m.a]) q.push(m),fk[m.a] = true;
                    m.a = (a*10+1)%n, m.str = str + "1";
                    if(!fk[m.a]) q.push(m),fk[m.a] = true;
                }
            }
        }
        return 0;
    }
    View Code
    #include <iostream>
    #include <cstdio>
    
    using namespace std;
    
    int n,flag;
    
    void dfs(unsigned long long a,int step){
        if(flag||step==50) return ;
        if(a%n==0) {flag = 1;printf("%I64u
    ",a);return ;}
        else{
            dfs(a*10,step+1);
            dfs(a*10+1,step+1);
        }
    }
    
    int main()
    {
        while(~scanf("%d",&n)&&n){
            flag = 0;
            dfs(1,0);
        }
        return 0;
    }
    View Code

    POJ - 3126 

    sf:求质数 + bfs  

    #include <iostream>
    #include <queue>
    #include <cstring>
    
    using namespace std;
    
    int n,m;
    int y[5];
    int ans[10000];
    queue<int> q;
    
    bool check(int x){
        for(int i=2;i*i<=x;i++) if(x%i==0) return false;
        return true;
    }
    
    void go(int x){
        for(int i=1;i<=4;i++){
            y[i]=x%10;
            x/=10;
        }
    }
    
    void dfs(){
        memset(ans,-1,sizeof ans);
        q.push(n);ans[n]=0;
        while(!q.empty()){
            int x = q.front();q.pop();
            if(x==m) break;
            go(x);
            int z = x - y[1];
            for(int i=0;i<=9;i++) if(i!=y[1]&&ans[z+i]<0&&check(z+i)) q.push(z+i),ans[z+i]=ans[x]+1;
            z = x - y[2]*10;
            for(int i=0;i<=9;i++) if(i!=y[2]&&ans[z+i*10]<0&&check(z+i*10)) q.push(z+i*10),ans[z+i*10]=ans[x]+1;
            z = x - y[3]*100;
            for(int i=0;i<=9;i++) if(i!=y[3]&&ans[z+i*100]<0&&check(z+i*100)) q.push(z+i*100),ans[z+i*100]=ans[x]+1;
            z = x - y[4]*1000;
            for(int i=1;i<=9;i++) if(i!=y[4]&&ans[z+i*1000]<0&&check(z+i*1000)) q.push(z+i*1000),ans[z+i*1000]=ans[x]+1;
        }
        while(!q.empty()) q.pop();
    }
    
    int main()
    {
        int _;cin>>_;
        while(_--){
            cin>>n>>m;
            dfs();
            if(ans[m]>=0) cout<<ans[m]<<endl;
            else cout<<"Impossible"<<endl;
        }
        return 0;
    }
    View Code
    #include <iostream>
    #include <cstring>
    #include <math.h>
    #include <queue>
    
    using namespace std;
    
    const int M = 1e5;
    
    int ans;
    bool ip[M+5];
    int dp[M+5];
    
    void isPrime(int n){
        memset(ip,true,sizeof ip);ip[0] = false,ip[1] = false;
        double db = n;
        int m = floor(sqrt(db));
        for(int i = 2;i<=m;i++) if(ip[i])
            for(int j = i;j*i <=n; j++) ip[j*i] = false;
    }
    
    void init(){
        ans = 0;
        memset(dp,-1,sizeof dp);
    }
    
    int bfs(int a,int b){
        queue<int> q;
        q.push(a);dp[a] = 0;
        while(!q.empty()){
            int p = q.front();q.pop();
            if(p == b) return dp[b];
            else{
                int x1 = p%10, y1 = p %100, z1 = p%1000;
                int x = p - x1, y = p - y1 + x1 , z = p - z1 + y1 ;
                for(int i=0;i<=9;i++){
                    int h = x+i;if(dp[h]==-1&&ip[h]) dp[h] = dp[p] + 1,q.push(h);
                    h = y+i*10;if(dp[h]==-1&&ip[h]) dp[h] = dp[p] + 1,q.push(h);
                    h = z+i*100;if(dp[h]==-1&&ip[h]) dp[h] = dp[p] + 1,q.push(h);
                    if(i==0) continue;
                    h = z1 + i*1000;if(dp[h]==-1&&ip[h]) dp[h] = dp[p] + 1,q.push(h);
                }
            }
        }
        return dp[b];
    }
    
    int main()
    {
        int _;cin>>_;
        isPrime(M);
        while(_--){
            init();
            int a,b;cin>>a>>b;
            cout<<bfs(a,b)<<endl;
        }
        return 0;
    }
    View Code

      质数单个求就是直接从2到sqrt(n)进行求余

    bool check(int x){
        for(int i=2;i*i<=x;i++) if(x%i==0) return false;
        return true;
    }

      筛选方法的话:就是从2到sqrt(n)取i,范围(最大到n),然后进行向后乘i

    void isPrime(int n){
        memset(ip,true,sizeof ip);ip[0] = false,ip[1] = false;
        double db = n;
        int m = floor(sqrt(db));
        for(int i = 2;i<=m;i++) if(ip[i])
            for(int j = i;j*i <=n; j++) ip[j*i] = false;
    }

    POJ - 3087 

    sf:简单模拟题 用到 set 进行排除string重复,然后使用string的assign函数进行取子串,

    #include <iostream>
    #include <set>
    
    using namespace std;
    
    int x,cnt,tt,y=1;
    string a,b,c,d;
    set<string> s;
    
    void slove(){
        s.clear();cnt = 0;
        cin>>x>>a>>b>>c;
        d=c;
        while(1){
            tt = 0;
            for(int i=0;i<x;i++) d[tt++]=b[i],d[tt++]=a[i];cnt++;
            if(d==c) {cout<<y++<<" "<<cnt<<endl;break;}
            if(s.count(d)==1) {cout<<y++<<" -1"<<endl;break;}
            a.assign(d,0,x);
            b.assign(d,x,x);
            s.insert(d);
        }
    }
    
    int main()
    {
        int _;cin>>_;
        while(_--){
            slove();
        }
        return 0;
    }
    View Code

    POJ - 3414 

    sf:bfs  难点在于 两个水杯容量x,y 与得水量z的关系   z必须能除掉 gcd(x,y);

    gcd函数,switch函数都是优美代码

    int gcd(int a,int b) {return b==0?a:gcd(b,a%b);}
    #include <iostream>
    #include <cstring>
    #include <string.h>
    #include <cstdio>
    #include <queue>
    
    using namespace std;
    
    int a,b,c;
    bool vis[101][101];
    
    struct node{
        int x,y,num;
    }k;
    
    struct mm{
        int number,pre;
    }akb[12000];
    
    int gcd(int a,int b) {return b==0?a:gcd(b,a%b);}
    
    void show(int x){
        if(akb[x].pre==-1) return ;
        show(akb[x].pre);
        switch(akb[x].number){
            case 1:puts("FILL(1)");break;
            case 2:puts("FILL(2)");break;
            case 3:puts("POUR(1,2)");break;
            case 4:puts("POUR(2,1)");break;
            case 5:puts("DROP(1)");break;
            case 6:puts("DROP(2)");
        }
    }
    
    void bfs(){
        k.x = 0 , k.y = 0 , k.num = 0;
        akb[0].pre = -1;
        vis[0][0]=true;
        queue<node> q;
        q.push(k);
        while(!q.empty()){
            node o = q.front();q.pop();
            int x , y ,num;
            for(int i=1;i<=6;i++){
                if(i==5) x = 0 , y = o.y ;
                else if(i==6) x = o.x , y = 0;
                else if(i==1) x = a , y = o.y;
                else if(i==2) x = o.x , y = b;
                else if(i==3){
                    x = o.x - min(o.x , b - o.y);
                    y = o.y + min(o.x , b - o.y);
                }
                else{
                    x = o.x + min(o.y , a - o.x);
                    y = o.y - min(o.y , a - o.x);
                }
                if(vis[x][y]) continue;
                vis[x][y]=true;
                num = o.num + 1;
                akb[x*101+y].number = i;
                akb[x*101+y].pre = o.x*101 + o.y;
    
                if(x == c || y == c) {cout<<num<<endl;show(x*101+y);return;}
    
                node f;f.x=x,f.y=y,f.num=num;
                q.push(f);
            }
        }
    }
    
    int main()
    {
        cin>>a>>b>>c;
        memset(vis,false,sizeof vis);
        if(c%gcd(a,b)) puts("impossible");
        else bfs();
        return 0;
    }
    View Code

    FZU - 2150 

    sf:暴力枚举两个草点开始烧 易错点:在于可以同地方烧

    #include <iostream>
    #include <queue>
    #include <cstring>
    
    using namespace std;
    
    int n,m,ans,cao,step=1;
    bool cp[15][15],fk[15][15];
    int xx[] = {1,0,0,-1};
    int yy[] = {0,1,-1,0};
    
    struct node{
        int x,y,z;
    };
    node k1,k2;
    
    void show(){
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)
                cout<<fk[i][j]<<" ";cout<<endl;}
    }
    void show2(){
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)
                cout<<cp[i][j]<<" ";cout<<endl;}
    }
    
    void init(){
        memset(fk,false,sizeof fk);
        ans = -1 , cao = 0 ;
        cin>>n>>m;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
        {
            char ch = getchar();
            if(ch == '
    ') ch = getchar();
            if(ch == '#') cao++,fk[i][j] = true;
        }
        //show();
    }
    
    bool check(int x,int y){
        return x>=0&&x<n&&y>=0&&y<m&&cp[x][y]&&fk[x][y];
    }
    
    void slove(int a,int b,int c,int d){
        memset(cp,true,sizeof cp);
        k1.x = a,k1.y = b,k1.z= 0; cp[a][b] = false;
        k2.x = c,k2.y = d,k2.z= 0; cp[c][d] = false;
        int cc = 2,cnt = 0;
        queue<node> q;q.push(k1);q.push(k2);
        while(!q.empty()){
            node p = q.front();q.pop();
            int x = p.x, y = p.y,z = p.z;
            //cout<<x<<" "<<y<<" "<<z<<endl;
            for(int i=0;i<4;i++) if(check(x+xx[i],y+yy[i])){
                p.x = x+xx[i], p.y = y+yy[i] , p.z = z + 1;q.push(p);
                cp[p.x][p.y] = false;cnt = p.z;cc++;
            }
        }
        //cout<<cc<<" "<<endl;
        //show2();
        if(cc == cao) ans = (ans==-1)? cnt : min(cnt,ans);
    }
    
    int main()
    {
        int _;cin>>_;
        while(_--){
            init();
            if(cao==1) {cout<<"Case "<<step++<<": "<<0<<endl;continue;}
            for(int a=0;a<n;a++)
                for(int b=0;b<m;b++)
            {
                if(!fk[a][b]) continue;
                for(int c=a;c<n;c++)
                    for(int d=(c==a)?b+1:0;d<m;d++)
                {
                    //show();
                    if(!fk[c][d]) continue;
                    //cout<<a<<" "<<b<<" "<<c<<" "<<d<<" "<<cao<<endl;
                    slove(a,b,c,d);
                }
            }
            cout<<"Case "<<step++<<": "<<ans<<endl;
        }
        return 0;
    }
    
    //优化 就是 可以用vector存储草坐标
    View Code
    #include <iostream>
    #include <cstring>
    #include <vector>
    #include <queue>
    #include <cstdio>
    
    using namespace std;
    
    const int inf = 1e9;
    
    int c[4]={1,0,-1,0};
    int d[4]={0,1,0,-1};
    int n,m;
    string s;
    bool vis[20][20];
    bool akb[20][20];
    struct node{
        int x,y,num;
    }e;
    vector<node> v;
    
    bool ok(int x,int y){
        if(x<0||x>n||y<0||y>m) return false;
        return true;
    }
    
    bool check(){
        for(int i = 0;i < v.size();i ++){
            e = v[i];
            int x = e.x , y = e.y;
            if(!vis[x][y]) return false;
        }
        return true;
    }
    
    int bfs(node a,node b){
        memset(vis , false , sizeof vis);
        queue<node> q;
        int h;
        a.num = 0 , b.num = 0;
        q.push(a);q.push(b);
        vis[a.x][a.y] = true;vis[b.x][b.y] = true;
        while(!q.empty()){
            e = q.front();q.pop();
            int x  , y ;
            h = e.num;
            node w;
            for(int i= 0;i < 4;i++){
                x = e.x + c[i] , y = e.y + d[i];
                if(ok(x ,y)&&!vis[x][y]&&akb[x][y]){
                    w.x = x , w.y = y;
                    w.num = e.num + 1;
                    vis[x][y]= true;
                    q.push(w);
                }
            }
        }
        return h;
    }
    
    int main()
    {
        int o = 1;int _;cin>>_;
        while(_--){
    
            memset(akb , false , sizeof akb);
            cin>>n>>m;
            v.clear();
            for(int i=0;i<n;i++){
                cin>>s;
                for(int j=0;j<m;j++)
                if(s[j]=='#'){
                    akb[i][j]=true;
                    e.x = i , e.y = j;
                    v.push_back(e);
                }
            }
    
            int minn = inf;
            for(int i = 0;i < v.size();i ++)
                for(int j = i;j < v.size();j ++){
                    int TnT = bfs(v[i],v[j]);
                    if(TnT<minn&&check()) minn = TnT;
                }
    
            cout<<"Case "<<o++<<": ";
            if(minn == inf) cout<<-1<<endl;
            else cout<<minn<<endl;
    
        }
        return 0;
    }
    View Code

    UVA - 11624 

    sf:bfs 火要比人先进队列 易错点在于 开头不止一个火苗

    这里使用了struct node 的有参构造

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <string.h>
    #include <queue>
    
    using namespace std;
    
    int n, m , u ,v;
    int xx[4] = { 0, -1, 0 ,1 };
    int yy[4] = { 1, 0, -1, 0 };
    char sm[1005][1005];
    struct node{
        int x,y,step,f;
        node(int xx,int yy,int sstep,int ff):x(xx),y(yy),step(sstep),f(ff) {};
    };
    
    bool bfs(){
        queue<node> q;
        for(int i=0;i<n;i++)
            for(int j= 0;j<m;j++)
                if(sm[i][j]=='F') sm[i][j] = '#' , q.push(node(i , j, 1, 0));
                else if(sm[i][j]=='J') sm[i][j] = '#' , u = i , v = j;
        q.push(node(u , v, 1, 1));
        while(!q.empty()){
            node e = q.front();q.pop();
            int x , y , s , f;x = e.x , y = e.y ,s = e.step , f = e.f;
            //cout<< x << " " << y <<" "<< s << " "<< f<<endl;
            if(f == 1&&(x==0||y==0||x==n-1||y==m-1)) {printf("%d
    ",s);return true;}
            for(int i = 0;i< 4;i ++){
                int a,b;
                a = x + xx[i] , b = y + yy[i];
                if(a<0||b<0||a>=n||b>=m||sm[a][b]=='#') continue;
                //cout<< a << " " << b <<" "<< s+1 << " "<< f<<endl;
                q.push(node(a,b,s+1,f));
                sm[a][b]='#';
            }
        }
        return false;
    }
    
    int main()
    {
        int _;scanf("%d",&_);
        while(_--){
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++) scanf("%s",sm[i]);
            if(!bfs()) puts("IMPOSSIBLE");
        }
        return 0;
    }
    View Code

    POJ - 3984 

    sf:简单bfs 必有答案 需要一个前缀记录函数

    #include <iostream>
    #include <queue>
    
    using namespace std;
    
    int prex[5][5];
    int prey[5][5];
    int w[5][5];
    int xx[] = {1,0,0,-1};
    int yy[] = {0,1,-1,0};
    
    struct node{
        int x,y;
        node(int xx,int yy): x(xx),y(yy) {};
    };
    
    void show(int x,int y){
        if(x==-1) return ;
        show(prex[x][y],prey[x][y]);
        cout<<"("<<x<<", "<<y<<")"<<endl;
    }
    
    int main()
    {
        for(int i=0;i<5;i++) for(int j=0;j<5;j++) cin>>w[i][j];
        prex[0][0] = -1 , prey[0][0] = -1;
        w[0][0] = 1;
        queue<node> q;q.push(node(0,0));
        while(!q.empty()){
            node p = q.front();q.pop();
            int x = p.x, y = p.y;
            for(int i=0;i<4;i++){
                int u = x +xx[i],v = y+yy[i];
                if(u<0||u>=5||v<0||v>=5||w[u][v]==1) continue;
                w[u][v]=1;
                prex[u][v] = x , prey[u][v] = y;
                q.push(node(u,v));
            }
        }
        show(4,4);
        return 0;
    }
    View Code

    HDU - 1241 

    sf:最小生成树思路 然后遍历 然后dfs

    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    int n,m;
    bool cp[101][101];
    int xx[] = {1,1,1,0,0,-1,-1,-1};
    int yy[] = {1,0,-1,1,-1,1,0,-1};
    
    bool check(int x,int y){
        return x>=0&&x<n&&y>=0&&y<m&&cp[x][y];
    }
    
    void dfs(int u,int v){
        for(int i=0;i<8;i++){
            int a = u+xx[i] , b = v + yy[i];
            if(check(a,b)){
                cp[a][b] = false;
                dfs(a,b);
            }
        }
    }
    
    void show(){
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++) cout<<cp[i][j]<<" ";cout<<endl;
        }
    }
    
    int main()
    {
        while(cin>>n>>m){
            if(n==0&&m==0) break;
            //cout<<n<<" "<<m<<endl;
            memset(cp,false,sizeof cp);
            for(int i=0;i<n;i++) for(int j=0;j<m;j++){
                char ch = getchar();//cout<<i<<" "<<j<<" "<<ch<<endl;
                while(ch!='@'&&ch!='*') ch = getchar();
                if(ch=='@') cp[i][j] = true;
            }
            //show();
            int ans = 0;
            for(int i=0;i<n;i++) for(int j=0;j<m;j++) if(cp[i][j]){
                cp[i][j] = false;ans++;dfs(i,j);
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code

    HDU - 1495 

    sf:bfs 然后易错点在于 :必须一个容器为空,

    #include <iostream>
    #include <queue>
    #include <cstring>
    
    using namespace std;
    
    int x,y,z,cnt;
    bool fk[1000005];
    struct node{
        int u,v,w,step;
        node(int uu,int vv,int ww,int ss):u(uu),v(vv),w(ww),step(ss) {};
    };
    
    int gcd(int a,int b) {return b==0?a:gcd(b,a%b);}
    
    bool bfs(){
        queue<node> q;q.push(node(x,0,0,0));fk[x*10000] = false;
        while(!q.empty()){
            node p = q.front();q.pop();
            int u = p.u , v = p.v , w = p.w,step = p.step;
            //cout<<u<<" "<<v<<" "<<w<<" "<<step<<" "<<cnt<<endl;
            if(u == cnt || v == cnt || w == cnt) {
                step = (!u||!v||!w)?step:step+1;
                cout<<step<<endl;return true;
            }
            int uu,vv,ww,tnt;
            if(u){
                uu = u+v>=y?u+v-y:0;
                vv = u+v>=y?y:u+v;
                ww = w;
                tnt = uu*10000+vv*100+ww;
                if(fk[tnt]){fk[tnt]=false;q.push(node(uu,vv,ww,step+1));}
                uu = u+w>=z?u+w-z:0;
                vv = v;
                ww = u+w>=z?z:u+w;
                tnt = uu*10000+vv*100+ww;
                if(fk[tnt]){fk[tnt]=false;q.push(node(uu,vv,ww,step+1));}
            }
            if(v){
                uu = u+v;
                vv = 0;
                ww = w;
                tnt = uu*10000+vv*100+ww;
                if(fk[tnt]){fk[tnt]=false;q.push(node(uu,vv,ww,step+1));}
                uu = u;
                vv = v+w>=z?v+w-z:0;
                ww = v+w>=z?z:v+w;
                tnt = uu*10000+vv*100+ww;
                if(fk[tnt]){fk[tnt]=false;q.push(node(uu,vv,ww,step+1));}
            }
            if(w){
                uu = u+w;
                vv = v;
                ww = 0;
                tnt = uu*10000+vv*100+ww;
                if(fk[tnt]){fk[tnt]=false;q.push(node(uu,vv,ww,step+1));}
                uu = u;
                vv = v+w>=y?y:v+w;
                ww = v+w>=y?v+w-y:0;
                tnt = uu*10000+vv*100+ww;
                if(fk[tnt]){fk[tnt]=false;q.push(node(uu,vv,ww,step+1));}
            }
        }
        return false;
    }
    
    int main()
    {
        while(cin>>x>>y>>z){
            if(x==0&&y==0&&z==0) break;
            if(x%2) {puts("NO");continue;}
            cnt = x/2;memset(fk,true,sizeof fk);
            if(cnt%gcd(x,gcd(y,z))) {puts("NO");continue;}
            if(!bfs()) puts("NO");
        }
        return 0;
    }
    View Code
    #include <iostream>
    #include <queue>
    #include <cstring>
    #include <string.h>
    #include <cstdio>
    
    using namespace std;
    
    int s, n, m;
    bool cp[101][100][100];
    struct node{
        int x,y,z,num;
        node(int xx,int yy,int zz,int nn):x(xx),y(yy),z(zz),num(nn) {};
    };
    node e = node(0,0,0,0);
    
    bool bfs(){
        int tt = s / 2;
        queue<node> q;
        q.push(node(s,0,0,0));
        cp[s][0][0] = true;
        while(!q.empty()){
            int a,b,c,x,y,z;
            e = q.front();q.pop();
            a = e.x , b = e.y , c = e.z;
            //cout<<a<<" "<<b<<" "<<c<<endl;
            if(a == tt|| b == tt || c == tt){
                if(!a||!b||!c) cout<<e.num<<endl;
                else cout<<e.num+1<<endl;
                return true;
            }
            for(int i=0;i<6;i++){
                if(i==0) if(b==n) continue;else x = a - min(a ,n - b) , y = b + min(a , n - b) , z = c;
                else if(i==1) x = a + b , y = 0 , z = c;
                else if(i==2) if(c==m) continue;else x = a - min(a ,m - c) , y = b , z = c + min(a ,m - c);
                else if(i==3) x = a + c , y = b , z = 0;
                else if(i==4) if(b==n) continue;else x = a , y = b + min(c ,n - b)  , z = c - min(c ,n - b);
                else if(i==5) if(c==m) continue;else x = a , y = b - min( b ,m - c ), z = c + min( b ,m - c );
                if(cp[x][y][z]) continue;cp[x][y][z] = true;
                q.push(node(x,y,z,e.num+1));
            }
        }
        return false;
    }
    
    int main()
    {
        while(cin>>s>>n>>m&&s){
            if(s%2) {puts("NO");continue;}
            memset(cp,false,sizeof cp);
            if(!bfs()) puts("NO");
        }
        return 0;
    }
    View Code

    HDU - 2612 

    sf:bfs加上两个记录长度的状态函数(类似求最短路径)

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    
    using namespace std;
    
    const int inf = 1e9;
    
    int n,m;
    int xx[4] = {1,0,0,-1};
    int yy[4] = {0,-1,1,0};
    char mp[205][205];
    int a[205][205];
    int b[205][205];
    int ans;
    
    struct node{
        int x , y , f;
        node(int xx , int yy , int ff):x(xx),y(yy),f(ff) {};
    };
    node e = node(0,0,0);
    
    int bfs(){
        ans = inf;
        memset(a,-1,sizeof a);
        memset(b,-1,sizeof b);
        queue<node> q;
        for(int i = 0;i<n;i++)
            for(int j = 0;j<m;j++)
                if(mp[i][j]=='Y') q.push(node(i , j , 0)) , a[i][j] = 0;
                else if(mp[i][j]=='M') q.push(node(i , j, 1)) , b[i][j] = 0;
        while(!q.empty()){
            int x, y , u, v;
            e = q.front();q.pop();
            x = e.x, y = e.y;
            for(int i=0;i<4;i++){
                u = x + xx[i] , v = y + yy[i];
                if(u<0||v<0||u>=n||v>=m) continue;
                if(mp[u][v]=='#') continue;
                if(e.f==0&&a[u][v]== -1){
                    a[u][v] = a[x][y] + 1;
                    if(mp[u][v]=='@'&&b[u][v]!=-1&&(a[u][v]+b[u][v] < ans)) ans = a[u][v]+b[u][v];
                    q.push(node(u,v,e.f));
                }
                else if(e.f==1&&b[u][v]==-1){
                    b[u][v] = b[x][y] + 1;
                    if(mp[u][v]=='@'&&a[u][v]!=-1&&(a[u][v]+b[u][v] < ans)) ans = a[u][v]+b[u][v];
                    q.push(node(u,v,e.f));
                }
            }
    
        }
        return ans;
    }
    
    int main()
    {
        while(cin>>n>>m){
            for(int i=0;i<n;i++) scanf("%s",mp[i]);
            cout<<bfs()*11<<endl;
        }
        return 0;
    }
    View Code

  • 相关阅读:
    linux学习8 运维基本功-Linux获取命令使用帮助详解
    持续集成学习11 jenkins和gitlab集成自动触发
    持续集成学习10 Pipline初探
    持续集成学习9 jenkins执行脚本
    持续集成学习8 jenkins权限控制
    持续集成学习7 jenkins自动化代码构建
    持续集成学习6 jenkins自动化代码构建
    持续集成学习5 jenkins自动化测试与构建
    持续集成学习4 jenkins常见功能
    【Hadoop离线基础总结】MapReduce增强(下)
  • 原文地址:https://www.cnblogs.com/BugClearlove/p/13663231.html
Copyright © 2020-2023  润新知