[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

原文地址:https://www.cnblogs.com/BugClearlove/p/13663231.html