kuangbin带你飞专题一 简单搜索 题解

目录

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

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

  • 总结:用时2天半终于把这个专题刷完了 对于最基础的dfs bfs 路径打印 状态转移也有了一点自己些微的理解 其实2天半可以压缩到1天半的 主要是自己太懒了。。。慢慢加油刷bin神的专题呀
  • 从大二下学期开始学算法 一开始就知道这个专题 一开始对于这个专题里的所有问题感觉都好难啊。。就直接放弃了 看lrj的书 现在看到这个专题还挺唏嘘的吧 突然觉得思维和想法也不是很难 果然是那个时候心不静&还是储量不够吗2333333

    A - 棋盘问题 POJ - 1321

    简单题 直接搜就好了 qwq 要注意的是$#$才是棋盘格 就是这样 喵


/*
 author:hdsdogge
 begin:
 end:
 cost:
 */
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T,n,m;
char a[maxn][maxn];
int ans;
bool row[maxn];
void dfs(int x,int step){
    if(step>=m){
        ans++;
        return ;
    }
    if(x>=n){
        return ;
    }
    for(int i=0;i<n;i++){                   //x是行
        if(a[x][i]==‘#‘&&!row[i]){
            row[i]=true;
            dfs(x+1,step+1);
            row[i]=false;
        }
    }
    dfs(x+1,step);
}
int main() {
    //freopen("test","r",stdin);
    //freopen("out","w",stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    while(cin>>n>>m&&n!=-1){
        ans=0;
        memset(row,false, sizeof(row));
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++)
                cin>>a[i][j];
        }
            dfs(0,0);
        cout<<ans<<endl;

    }
    return 0;
}

B - Dungeon Master POJ - 2251

一个水平上下左右&垂直上下的bfs第一次看的时候没看懂题目23333

/*
 author:hdsdogge
 begin:
 end:
 cost:
 */
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T,n,m,l,r,c;
int step[maxn][maxn][maxn];
struct node{                        //node是第几层  r c表示几行几列
    int x,y,z;
    char v;
};
char maze[maxn][maxn][maxn];
int dx[]={1,-1,0,0,0,0};
int dy[]={0,0,1,-1,0,0};
int dz[]={0,0,0,0,1,-1};
int main() {
    //freopen("test","r",stdin);
    //freopen("out","w",stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    while(cin>>l>>r>>c&&l+r+c){
        int s_l,s_r,s_c;
        int e_l,e_r,e_c;
        node a;
        node Begin;
        node End;
        bool ok=false;
        memset(step,0, sizeof(step));
        for(int i=0;i<l;i++) {
            for (int j = 0; j < r; j++) {
                for (int k = 0; k < c; k++) {
                    cin >>a.v;
                    a.x=i;
                    a.y=j;
                    a.z=k;
                    maze[i][j][k]=a.v;
                    if (a.v == ‘S‘) {
                         Begin=a;
                    }
                    if (a.v == ‘E‘) {
                         End=a;
                    }
                }
            }
        }
        queue<node> q;
        q.push(Begin);
        while(q.size()){
            node temp=q.front();
            q.pop();
            if(temp.x==End.x&&temp.y==End.y&&temp.z==End.z){
                cout<<"Escaped in "<<step[End.x][End.y][End.z]<<" minute(s)."<<endl;
                ok=true;
                break;
            }
            for(int i=0;i<6;i++){
                node nxt=temp;
                nxt.x+=dx[i];
                nxt.y+=dy[i];
                nxt.z+=dz[i];
                if(nxt.x>=0&&nxt.x<l&&nxt.y>=0&&nxt.y<r&&nxt.z>=0&&nxt.z<c&&maze[nxt.x][nxt.y][nxt.z]!=‘#‘){
                    q.push(nxt);
                    step[nxt.x][nxt.y][nxt.z]=step[temp.x][temp.y][temp.z]+1;
                    maze[nxt.x][nxt.y][nxt.z]=‘#‘;
                }
            }
        }
        if(!ok){
            cout<<"Trapped!"<<endl;
        }

    }
    return 0;
}

C - Catch That Cow POJ - 3278

没啥好讲的 简单bfs就完事了


/*
 author:hdsdogge
 begin:
 end:
 cost:
 */
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1E5;
int T,n,m;
int step[INF*2];
int main() {
    //freopen("test","r",stdin);
    //freopen("out","w",stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    while(cin>>n>>m){
        queue<int> q;
        q.push(n);
        step[n]=1;
        while(q.size()){
            int temp=q.front();
            q.pop();
            if(temp==m){
                cout<<step[m]-1<<endl;
                break;
            }
            if(temp*2<INF*2&&!step[temp*2]){
                q.push(temp*2);
                step[temp*2]=step[temp]+1;
            }
            if(temp-1>=0&&!step[temp-1]){
                q.push(temp-1);
                step[temp-1]=step[temp]+1;
            }
            if(temp+1<INF&&!step[temp+1]){
                q.push(temp+1);
                step[temp+1]=step[temp]+1;
            }
        }
    }
    return 0;
}

D - Fliptile POJ - 3279

这个就是传说中的状态转移啦 。就是说前一层的状态一定取决于下一层的状态 也就是说只要确定第一层的状态 其他剩下的状态都是确定的 同时这个问题也是开关问题的延伸(二维开关问题)


/*
 author:hdsdogge
 begin:
 end:
 cost:
 */
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T,n,m;
int a[maxn][maxn];
const int dx[]={-1,1,0,0,0};
const int dy[]={0,0,0,-1,1};
int opt[maxn][maxn];
int filp[maxn][maxn];
int get_color(int x,int y){
    int v=a[x][y];
    for(int i=0;i<5;i++){
        int nx=x+dx[i];
        int ny=y+dy[i];
        if(nx>=0&&nx<n&&ny>=0&&ny<m){
            v+=filp[nx][ny];
        }
    }
    return v%2;
}

int clac(){
    for(int i=1;i<n;i++){
        for(int j=0;j<m;j++){
            if(get_color(i-1,j)!=0){
                filp[i][j]=1;
            }
        }
    }
    for(int i=0;i<m;i++) {
        if (get_color(n - 1, i) != 0) {
            return -1;
        }
    }
    int res=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            res+=filp[i][j];
        }
    }
    return res;
}

int main() {
    //freopen("test","r",stdin);
    //freopen("out","w",stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    while(cin>>n>>m){
        int res=-1;
        int num;
        for(int i=0;i<n;i++) {
            for (int j = 0; j < m; j++) {
                cin >> a[i][j];
            }
        }
        for(int i=0;i<1<<m;i++){
            memset(filp,0, sizeof(filp));
            for(int j=0;j<m;j++){
                filp[0][m-j-1]=i>>j&1;
            }
            num=clac();
            if(num>=0&&(res<0||res>num)){
                res=num;
                memcpy(opt,filp, sizeof(filp));
            }
        }
        if(res>=0) {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if (j == 0)
                        cout << opt[i][j];
                    else
                        cout << " " << opt[i][j];
                }
                cout << endl;
            }
        } else cout<<"IMPOSSIBLE"<<endl;
    }
    return 0;
}

E - Find The Multiple POJ - 1426

题意:给定一个数字 找一串01串能整除这个数 其实这个题目的位数没有那么可怕 。(至少没有100位) longlong是够用的

所以说01串直接bfs可得


/*
 author:hdsdogge
 begin:
 end:
 cost:
 */
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
ll T,n,m;
char a[maxn][maxn];
queue<ll> q;
int main() {
    //freopen("test","r",stdin);
    //freopen("out","w",stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    while(cin>>n&&n){
      while(q.size())
          q.pop();
      q.push(1);
      while(q.size()){
          ll temp=q.front();
          q.pop();
          if(temp%n==0){
              cout<<temp<<endl;
              break;
          }
          q.push(temp*10);
          q.push(temp*10+1);

      }
    }
    return 0;
}

F - Prime Path POJ - 3126

先打一个素数表

之后bfs一位一位搜啊。。


/*
 author:hdsdogge
 begin:
 end:
 cost:
 */
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include<sstream>
#include<ctype.h>
using namespace std;
const int maxn=10000+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T,n,m;
map<int,int> mp;
queue<int> q;
int vis[maxn];
int main() {
    freopen("test","r",stdin);
    freopen("out","w",stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    for(int i=1000;i<=9999;i++){
        bool flag=true;
        for(int j=2;j*j<=i;j++){
            if(i%j==0){
                flag=false;
                break;
            }
        }
        if(flag)
            mp[i]=1;
    }

    cin>>T;
    while(T--){
        cin>>n>>m;
        int a,b,c,d;
        memset(vis,0, sizeof(vis));

        while(q.size()) {
            q.pop();
        }
        vis[n]=1;
        q.push(n);
        while(q.size()){
            int temp=q.front();
            q.pop();
            if(temp==m) {
                cout << vis[m] << endl;
                break;
            }
            a=temp/1000;
            b=temp/100%10;
            c=temp/10%10;
            d=temp%10;
            for(int i=1;i<=9;i++){
                if(mp[i*1000+b*100+c*10+d]==1&&vis[i*1000+b*100+c*10+d]==0){
                    q.push(i*1000+b*100+c*10+d);
                    vis[i*1000+b*100+c*10+d]=vis[temp]+1;
                }
            }
            for(int i=1;i<=9;i++){
                if(mp[a*1000+i*100+c*10+d]==1&&vis[a*1000+i*100+c*10+d]==0){
                    q.push(a*1000+i*100+c*10+d);
                    vis[a*1000+i*100+c*10+d]=vis[temp]+1;
                }
            }
            for(int i=1;i<=9;i++){
                if(mp[a*1000+b*100+i*10+d]==1&&vis[a*1000+b*100+i*10+d]==0){
                    q.push(a*1000+b*100+i*10+d);
                    vis[a*1000+b*100+i*10+d]=vis[temp]+1;
                }
            }
            for(int i=1;i<=9;i++){
                if(mp[a*1000+b*100+c*10+i]==1&&vis[a*1000+b*100+c*10+i]==0){
                    q.push(a*1000+b*100+c*10+i);
                    vis[a*1000+b*100+c*10+i]=vis[temp]+1;
                }
            }

        }
    }
    return 0;
}

G - Shuffle‘m Up POJ - 3087

照题意模拟就行了 不过要确定最后上面的是s1 还是下面的是s1

(其实我觉得这题可能划分为模拟题更好一点 )


/*
 author:hdsdogge
 begin:
 end:
 cost:
 */
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T,n,m;
char a[maxn][maxn];
int main() {
    //freopen("test","r",stdin);
    //freopen("out","w",stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    cin>>T;
    int kase=1;
    while(T--){
        cin>>n;
        string s1,s2,s12;
        cin>>s1>>s2>>s12;
        map<string,int > mp;
        mp.clear();
        int ans=0;
        while(1){
            string temp;
            for(int i=0;i<n;i++){
                temp+=s2[i];
                temp+=s1[i];
            }
            ans++;
            if(temp==s12){
                cout<<kase<<" "<<ans<<endl;
                break;
            }
            else if(mp[temp]==1){
                cout<<kase<<" "<<-1<<endl;
                break;
            }
            mp[temp]=1;
            s2=temp.substr(n,2*n);
            s1=temp.substr(0,n);
        }
        kase++;
    }
    return 0;
}

H - Pots POJ - 3414

讲道理这道题应该是这套题里最难的一道了吧。。。

首先呢这道题的前置知识有

K,M

其实这道题就是k和m的结合版 不过因为输出impossible大写了wa了一发就是了qwq

感觉我的代码写的好丑- -

   /*
     author:hdsdogge
     begin:
     end:
     cost:
    */
    #include<iostream>
    #include<string>
    #include<queue>
    #include<map>
    #include<stack>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<vector>
    #include<bitset>
    #include<cstdlib>
    #include<list>
    #include <sstream>
    #include<ctype.h>
    using namespace std;
    const int maxn=200+10;
    typedef pair<int,int> P;
    typedef long long ll;
    const double PI = acos(-1.0);
    const double eps = 1e-6;
    const int INF = 1000000000;
    int T,n,m;
    struct node{
        int a;
        int b;
        int step;
        int m1;
        int m2;
        node *pre;
        node():step(0),a(0),b(0){}
    };

    int A,B,C;
    queue<node> q;
    int main() {
        freopen("test","r",stdin);
        freopen("out","w",stdout);
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        while(cin>>A>>B>>C) {
            while (q.size())
                q.pop();

            node a[maxn][maxn];
            int ans;
            for (int i = 0; i <= A; i++) {
                for (int j = 0; j <= B; j++) {
                    a[i][j].a = i;
                    a[i][j].b = j;
                }
            }
            a[0][0].pre = NULL;
            q.push(a[0][0]);
            int sa = INF, sb = INF;

            while (q.size()) {
                node temp = q.front();
                q.pop();
                if (temp.a == C || temp.b == C) {
                    cout << temp.step << endl;
                    ans = temp.step;
                    sa = temp.a;
                    sb = temp.b;
                    break;
                }
                for (int i = 1; i <= 3; i++) {
                    for (int j = 1; j <= 2; j++) {
                        node temp1 = temp;
                        if (i == 1) {
                            if (j == 1) {                                  // 给A倒水 i的意思几个方式
                                if (temp1.a < A) {
                                    temp1.a = A;
                                }
                            } else if (j == 2) {
                                if (temp1.b < B) {
                                    temp1.b = B;
                                }
                            }
                        }

                        if (i == 2) {
                            if (j == 1 && temp1.a) {                               //把1里的水倒进2里
                                if (temp1.a > B - temp1.b&&temp1.b<B) {
                                    temp1.a -= B - temp1.b;
                                    temp1.b = B;
                                } else {
                                    temp1.b += temp1.a;
                                    temp1.a = 0;
                                }
                            }
                            if (j == 2 && temp1.b) {
                                if (temp1.b > A - temp1.a&&temp1.a<A) {
                                    temp1.b -= A - temp1.a;
                                    temp1.a = A;
                                } else {
                                    temp1.a += temp1.b;
                                    temp1.b = 0;
                                }
                            }
                        }
                        if (i == 3) {
                            if (j == 1 && temp1.a) {
                                temp1.a = 0;
                            } else if (j == 2 && temp1.b) {
                                temp1.b = 0;
                            }
                        }
                        if (a[temp1.a][temp1.b].step == 0 && temp1.a >= 0 && temp1.a <= A && temp1.b >= 0 && temp1.b <= B) {
                            a[temp1.a][temp1.b].pre = &a[temp.a][temp.b];
                            a[temp1.a][temp1.b].m1 = i;
                            a[temp1.a][temp1.b].m2 = j;
                            a[temp1.a][temp1.b].step = a[temp.a][temp.b].step + 1;
                            q.push(a[temp1.a][temp1.b]);
                        }
                    }
                }
            }
            if (sa != INF) {
                node *head;
                head = &a[sa][sb];
                vector<P> v;
                while (head != NULL) {
                    v.push_back(P(head->m1, head->m2));
                    head = head->pre;
                    if (v.size() == ans)
                        break;
                }

                for (int i = v.size() - 1; i >= 0; i--) {
                    if (v[i].first == 1) {
                        cout << "FILL(" << v[i].second << ")" << endl;
                    }

                    if (v[i].first == 2) {
                        if (v[i].second == 1) {
                            cout << "POUR(1,2)" << endl;
                        } else {
                            cout << "POUR(2,1)" << endl;
                        }
                    }
                    if (v[i].first == 3) {
                        cout << "DROP(" << v[i].second << ")" << endl;
                    }
                }
            } else {
                cout << "impossible" << endl;
            }
        }
        return 0;
    }

I - Fire Game FZU - 2150

这道题就是说给你两个人 放火 看看能不能把草放光

先用dfs求一下联通块$x$如果$x>2$则不能 其余情况均可以

但是~~

坑点在于

草不一定>=2 也有可能草=1 这样一个人点火就行了

思维定势啊 话说这个题目真的有点恶趣味233333


/*
 author:hdsdogge
 begin:
 end:
 cost:
 */
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
#include<algorithm>
using namespace std;
const int maxn=200+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 100000;
int T,n,m;
char a[maxn][maxn];
int vis[maxn][maxn];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
int cnt;
char temp[maxn][maxn];
bool judge(int x,int y){
    if(x>=0&&x<n&&y>=0&&y<m)
        return true;
    return false;
}
bool check(){
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(a[i][j]==‘.‘)
                return false;
        }
    }
    return true;
}
void dfs(int x,int y,char c){
    temp[x][y]=c;
    for(int i=0;i<4;i++){
        int nx=x+dx[i];
        int ny=y+dy[i];
        if(judge(nx,ny)&&temp[nx][ny]==‘#‘){
            dfs(nx,ny,c);
        }
    }
}
int bfs(int sx1,int sy1,int sx2,int sy2){
    queue<P> q;
    memset(vis,0, sizeof(vis));
    q.push(P(sx1,sy1));
    q.push(P(sx2,sy2));
    vis[sx1][sy1]=1;
    vis[sx2][sy2]=1;
    int ans=1;
    while(q.size()) {
        P p=q.front();
        q.pop();
        for (int i = 0; i < 4; i++) {
            int nx=p.first+dx[i];
            int ny=p.second+dy[i];
            if(nx>=0&&nx<n&&ny>=0&&ny<m&&vis[nx][ny]==0&&a[nx][ny]==‘#‘){
                vis[nx][ny]=vis[p.first][p.second]+1;
                ans=max(ans,vis[nx][ny]);
                q.push(P(nx,ny));
            }
        }
    }
    return ans;
}
void print(){
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cout<<vis[i][j];
        }
        cout<<endl;
    }
}
int main() {
    //freopen("test","r",stdin);
    //freopen("out","w",stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    cin>>T;
    int kase=0;
    while(T--){
        cin>>n>>m;
        kase++;
        cnt=0;
        int res=INF;
        vector<P> v1,v2;
        for(int i=0;i<n;i++) {
            for (int j = 0; j < m; j++) {
                cin >> a[i][j];
            }
        }
        memcpy(temp,a,sizeof(temp));
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(temp[i][j]==‘#‘){
                    if(cnt==0)
                        dfs(i,j,‘?‘);
                    if(cnt==1)
                        dfs(i,j,‘/‘);
                    cnt++;
                }
            }
        }
       // print();
        if(cnt>2)
            cout<<"Case "<<kase<<": "<<"-1"<<endl;
        else{
            if(cnt==1){
                for(int i=0;i<n;i++){
                    for(int j=0;j<m;j++){
                        if(a[i][j]==‘#‘){
                            v1.push_back(P(i,j));
                        }
                    }
                }
                if(v1.size()==1){
                    res=0;
                }
                else {
                    for (int i = 0; i < v1.size(); i++) {
                        for (int j = i + 1; j < v1.size(); j++) {
                            res = min(res, (bfs(v1[i].first, v1[i].second, v1[j].first, v1[j].second) - 1));
                        }
                    }
                }
                cout<<"Case "<<kase<<": "<<res<<endl;
            }else{
                for(int i=0;i<n;i++) {
                    for (int j = 0; j < m; j++) {
                        if (temp[i][j] == ‘?‘)
                            v1.push_back(P(i, j));
                        if (temp[i][j] == ‘/‘)
                            v2.push_back(P(i, j));
                    }
                }
                for(int i=0;i<v1.size();i++){
                    for(int j=0;j<v2.size();j++){
                        res=min(res,(bfs(v1[i].first,v1[i].second,v2[j].first,v2[j].second)-1));
                       // print();
                    }
                }
                cout<<"Case "<<kase<<": "<<res<<endl;
            }
        }

    }
    return 0;
}

J - Fire! UVA - 11624

先将火烧到的时间处理一下 之后呢再处理人的位置 两次bfs 如果人到的时间<火到的时间 就将他压入队列中 要注意的是火可能有多个


/*
 author:hdsdogge
 begin:
 end:
 cost:
 */
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
#include<algorithm>
using namespace std;
const int maxn=2000+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 2000000;
int T,n,m;
int t[maxn][maxn];
int vis[maxn][maxn];
char a[maxn][maxn];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
queue<P> q;
int main() {
    freopen("test","r",stdin);
    freopen("out","w",stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    cin>>T;
    while(T--){
        cin>>n>>m;
        int sx,sy;
        bool ok=false;
        while(q.size())
            q.pop();
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                t[i][j]=INF;
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                vis[i][j]=0;
            }
        }

        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                cin>>a[i][j];
                if(a[i][j]==‘F‘){
                    q.push(P(i,j));
                    t[i][j]=1;
                }
                else if(a[i][j]==‘J‘){
                    sx=i;
                    sy=j;
                }
            }
        }
        while(q.size()){
            P p=q.front();
            q.pop();
            for(int i=0;i<4;i++){
                int nx=p.first+dx[i];
                int ny=p.second+dy[i];
                if(nx>=0&&nx<n&&ny>=0&&ny<m&&a[nx][ny]!=‘#‘&&t[nx][ny]==INF){
                    t[nx][ny]=t[p.first][p.second]+1;
                    q.push(P(nx,ny));
                }
            }
        }

        vis[sx][sy]=1;
        q.push(P(sx,sy));
        while(q.size()&&!ok){
            P p=q.front();
            q.pop();
            if(p.first==n-1||p.first==0||p.second==m-1||p.second==0){
                cout<< vis[p.first][p.second]<<endl;
                ok=true;
                break;
            }
            for(int i=0;i<4;i++){
                int nx=p.first+dx[i];
                int ny=p.second+dy[i];
                if(nx>=0&&nx<n&&ny>=0&&ny<m&&a[nx][ny]!=‘#‘&&vis[nx][ny]==0){
                    vis[nx][ny]=vis[p.first][p.second]+1;
                    if(vis[nx][ny]<t[nx][ny]) {
                        q.push(P(nx, ny));
                    }
                }
            }
        }
        if(!ok){
            cout<<"IMPOSSIBLE"<<endl;
        }
    }
    return 0;
}

K - 迷宫问题 POJ - 3984

bfs追溯路径问题 我是用链表来存储路径的(其实是网上写的递归我看不懂。。)

存储一个前置节点就好啦


/*
 author:hdsdogge
 begin:
 end:
 cost:
 */
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T,n,m;
int a[5][5];
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
struct node{
    int step;
    int x;
    int y;
    node *pre;
    node():step(0){}
};

queue<node> q;
int main() {
    //freopen("test","r",stdin);
    //freopen("out","w",stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    node s[5][5];
    while(q.size())
        q.pop();
    for(int i=0;i<5;i++){
        for(int j=0;j<5;j++){
            cin>>a[i][j];
            s[i][j].x=i;
            s[i][j].y=j;
        }
    }

    s[0][0].step=1;
    s[0][0].x=0;
    s[0][0].y=0;
    s[0][0].pre=NULL;
    q.push(s[0][0]);
    while(q.size()){
        node temp=q.front();
        q.pop();
        if(temp.x==4&&temp.y==4){
            break;
        }
        for(int i=0;i<4;i++){
            int nx=temp.x+dx[i];
            int ny=temp.y+dy[i];
            if(nx>=0&&nx<5&&ny>=0&&ny<5&&a[nx][ny]==0&&s[nx][ny].step==0){
                s[nx][ny].step=temp.step+1;
                s[nx][ny].pre=&s[temp.x][temp.y];
                q.push(s[nx][ny]);
            }
        }
    }
    int x=4,y=4;
    node *head;
    head=&s[4][4];
    vector<P> v;
    while(head!=NULL){
        v.push_back(P(head->x,head->y));
        head=head->pre;
    }
    for(int i=v.size()-1;i>=0;i--){
        cout<<"("<<v[i].first<<", "<<v[i].second<<")"<<endl;
    }
    return 0;
}

L - Oil Deposits HDU - 1241

没啥好说的,dfs入门水题 求联通块问题


/*
 author:hdsdogge
 begin:
 end:
 cost:
 */
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>

using namespace std;
const int maxn = 100 + 10;
typedef pair<int, int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T, n, m;
char a[maxn][maxn];
int dx[]={-1,-1,0,1,1,1,0,-1};
int dy[]={0,1,1,1,0,-1,-1,-1};
void dfs(int x,int y){
    a[x][y]=‘*‘;
    for(int i=0;i<8;i++){
        int nx=x+dx[i];
        int ny=y+dy[i];
        if(nx>=0&&nx<n&&ny>=0&&ny<m&&a[nx][ny]!=‘*‘){
            dfs(nx,ny);
        }
    }
}
int main() {
    //freopen("test", "r", stdin);
    //freopen("out", "w", stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    while (cin >> n >> m&&n+m) {
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                cin >> a[i][j];
            int ans=0;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++){
                if(a[i][j]==‘@‘){
                    dfs(i,j);
                    ans++;
                }
            }
            cout<<ans<<endl;
    }
    return 0;
}

M - 非常可乐 HDU - 1495

这个就是一个状态的问题额 设定状态一步步dfs直到为空或者到要的结果就好了哦


/*
 author:hdsdogge
 begin:
 end:
 cost:
 */
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
using namespace std;
const int maxn=100+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000000;
int T,s,n,m;
struct node{
    int cur[3];
};
int b[3];
int step[maxn][maxn][maxn];
queue<node> q;
int main() {
    //freopen("test","r",stdin);
    //freopen("out","w",stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    while(cin>>b[0]>>b[1]>>b[2]&&(b[0]+b[1]+b[2])){
        node a;
        while(q.size())
            q.pop();
        a.cur[0]=b[0];
        a.cur[1]=0;
        a.cur[2]=0;
        memset(step,0, sizeof(step));
        step[b[0]][0][0]=1;
        q.push(a);
        bool ok=false;

        int half=b[0]/2;
        if(b[0]%2==1)
            ok=false;
        else {
            while (q.size()&&!ok) {
                a=q.front();
                q.pop();
                for(int i=0;i<3;i++){
                    for(int j=0;j<3;j++) {
                        node temp = a;
                        if (i == j)
                            continue;
                        if((temp.cur[0]==half&&temp.cur[1]==half)||(temp.cur[1]==half&&temp.cur[2]==half)||(temp.cur[0]==half&&temp.cur[2]==half)){
                            ok=true;
                            cout<<step[temp.cur[0]][temp.cur[1]][temp.cur[2]]-1<<endl;
                            i=5;
                            break;
                        }
                        if (temp.cur[i] > 0) {
                            if (temp.cur[i] >= b[j] - temp.cur[j]) {
                                temp.cur[i]-= b[j] - temp.cur[j];
                                temp.cur[j]=b[j];
                            }else{
                                temp.cur[j]+=temp.cur[i];
                                temp.cur[i]=0;
                            }
                        }
                        if(step[temp.cur[0]][temp.cur[1]][temp.cur[2]]==0){
                            step[temp.cur[0]][temp.cur[1]][temp.cur[2]]=step[a.cur[0]][a.cur[1]][a.cur[2]]+1;
                            q.push(temp);
                        }
                    }
                }
            }
        }
        if(!ok){
            cout<<"NO"<<endl;
        }
    }
    return 0;
}

N - Find a way HDU - 2612

一开始想的是每一个[email protected]$也就是kfc bfs一下 但是T了qwq

后来想了想两次bfs就好了 然后去每个kfc的最小值喵


/*
 author:hdsdogge
 begin:
 end:
 cost:
 */
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<bitset>
#include<cstdlib>
#include<list>
#include <sstream>
#include<ctype.h>
#include<algorithm>
using namespace std;
const int maxn=200+10;
typedef pair<int,int> P;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 1000000;
int T,n,m;
char a[maxn][maxn];
int vis[maxn][maxn][2];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
int bfs1(int sx,int sy){
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            vis[i][j][0]=INF;
        }
    }
    queue<P> q;
    q.push(P(sx,sy));
    vis[sx][sy][0]=0;
    while(q.size()){
        P p=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            P temp=p;
            int nx=temp.first+dx[i];
            int ny=temp.second+dy[i];
            if(nx>=0&&nx<n&&ny>=0&&ny<m&&(a[nx][ny]==‘@‘||a[nx][ny]==‘.‘)&&vis[nx][ny][0]==INF){
                vis[nx][ny][0]=vis[p.first][p.second][0]+1;
                q.push(P(nx,ny));
            }
        }
    }
}
int bfs2(int sx,int sy){
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            vis[i][j][1]=INF;
        }
    }
    queue<P> q;
    q.push(P(sx,sy));
    vis[sx][sy][1]=0;
    while(q.size()){
        P p=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            P temp=p;
            int nx=temp.first+dx[i];
            int ny=temp.second+dy[i];
            if(nx>=0&&nx<n&&ny>=0&&ny<m&&(a[nx][ny]==‘@‘||a[nx][ny]==‘.‘)&&vis[nx][ny][1]==INF){
                vis[nx][ny][1]=vis[p.first][p.second][1]+1;
                q.push(P(nx,ny));
            }
        }
    }
}
int main() {
    //freopen("test","r",stdin);
    //freopen("out","w",stdout);
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    while(cin>>n>>m){
        int ans=INF;
        int sx,sy,ex,ey;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                cin>>a[i][j];
                if(a[i][j]==‘Y‘){
                    sx=i;
                    sy=j;
                }
                else if(a[i][j]==‘M‘){
                    ex=i;
                    ey=j;
                }
            }
        }
        bfs1(sx,sy);
        bfs2(ex,ey);
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(a[i][j]==‘@‘) {
                    ans = min(vis[i][j][0]+vis[i][j][1], ans);
                }
            }
        }
        cout<<ans*11<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/hdsdogge/p/9403858.html

时间: 2024-12-20 15:37:38

kuangbin带你飞专题一 简单搜索 题解的相关文章

[kuangbin带你飞]专题一 简单搜索 - E - Find The Multiple

1 //Memory Time 2 //2236K 32MS 3 4 #include<iostream> 5 using namespace std; 6 7 int mod[524286]; //保存每次mod n的余数 8 //由于198的余数序列是最长的 9 //经过反复二分验证,436905是能存储198余数序列的最少空间 10 //但POJ肯定又越界测试了...524286是AC的最低下限,不然铁定RE 11 12 int main(int i) 13 { 14 int n; 15

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

题来:链接https://vjudge.net/problem/OpenJ_Bailian-132 J - 棋盘问题 1.题目: 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C.Input 输入含有多组测试数据. 每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目. n <= 8 , k

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

一直拖.放了放久.受不了 A - 棋盘问题 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C. Input 输入含有多组测试数据. 每组数据的第

[kuangbin带你飞]专题一 简单搜索 A - 棋盘问题

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C. Input 输入含有多组测试数据. 每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目. n <= 8 , k <= n 当为-1 -1时表示输入结束. 随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白

Catch That Cow POJ - 3278 [kuangbin带你飞]专题一 简单搜索

Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two m

[kuangbin带你飞]专题一 简单搜索 bfs B - Dungeon Master

B - Dungeon Master You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled with rock. It takes one minute to move one unit north, south, east, west, up or down. You c

[kuangbin带你飞]专题一 简单搜索 - M - 非常可乐

1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 bool cup[105][105][105]; 8 struct dot 9 { 10 int a; 11 int b; 12 int c; 13 int s; 14 }; 15 int x, y,

[kuangbin带你飞]专题一 简单搜索 - L - Oil Deposits

1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 char g[105][105]; 8 int x, y, ans; 9 int dx[3]={1,0,-1}; 10 int dy[3]={1,0,-1}; 11 bool sscanf() 12

Dungeon Master POJ - 2251 [kuangbin带你飞]专题一 简单搜索

You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled with rock. It takes one minute to move one unit north, south, east, west, up or down. You cannot move diagonal