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

一开始想的是每一个$@$也就是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;
}


猜你喜欢

转载自www.cnblogs.com/hdsdogge/p/9403858.html