1.非常可乐

思路,用到BFS,6个方向搜索,S-A,A-S,S-B,B-S,A-B,B-A;

  • f[i][j][k]代表这三个杯子中分别含有[i][j][k]的需要的倒水的次数

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int f[110][110][110];
    int k[4];
    struct  node{
    int w[3];
    };
    int main(){
    while (cin>>k[0]>>k[1]>>k[2],k[0]&&k[1]&&k[2]){
        memset(f,-1,sizeof f);
        queue<node>q;
        f[k[0]][0][0]=0;
        q.push({k[0],0,0});
        bool st=false;
        if(k[0]&1){
            cout<<"NO\n";
            continue;
        }
    
        while (!q.empty()){
            auto t=q.front();
            q.pop();
            int ans=f[t.w[0]][t.w[1]][t.w[2]];
            if(t.w[0]==t.w[1]&&!t.w[2]){
                cout<<ans<<endl;
                st= true;
                break;
            }
            if(t.w[0]==t.w[2]&&!t.w[1]){
                cout<<ans<<endl;
                st= true;
                break;
            }
            if(t.w[2]==t.w[1]&&!t.w[0]){
                cout<<ans<<endl;
                st= true;
                break;
            }
            int p[3];
            for (int i = 0; i <3 ; ++i) {
                for (int j = 0; j <3 ; ++j) {
                    p[0]=t.w[0],p[1]=t.w[1],p[2]=t.w[2];
                    if(i!=j&&(p[i])&&p[j]!=k[j]){
                        int h=min(p[i],k[j]-p[j]);
                        p[i]-=h;
                        p[j]+=h;
                        if(f[p[0]][p[1]][p[2]]==-1){
                            f[p[0]][p[1]][p[2]]= ans+1;
                            q.push({p[0],p[1],p[2]});
                        }
                    }
                }
            }
        }
        if(st==false){
            puts("NO");
        }
    }
    }

    2.哈密顿绕行世界问题

    思路:建图时注意去重,主要是记录路径,用&vector记录路径,记得回溯剪枝,排序边保证按照字典序排列

    代码:

    #include<bits/stdc++.h>
    using namespace  std;
    vector<int >q[25];
    int cnt=1;
    int vis[25];
    int qd;
    void dfs(vector<int >&t,int u){
    if(t.size()==20){
        int p=0;
        for (int i = 0; i <q[t.back()].size() ; ++i) {
            if(q[t.back()][i]==qd){
                 p=1;
            }
        }
        if(p){
            t.push_back(qd);
            cout<<cnt<<": ";
            cnt++;
            for (auto x:t) {
                cout<<" "<<x;
            }
            cout<<endl;
            t.pop_back();
        }
    }
    for (int i = 0; i <q[u].size() ; ++i) {
        int d=q[u][i];
        if(vis[d]==0){
            t.push_back(d);
            vis[d]=1;
            dfs(t,d);
            t.pop_back();
            vis[d]=0;
        }
    }
    return;
    }
    int main(){
    set<int >st[25];
    for (int i = 1; i <=20 ; ++i) {
        int x,y,z;
        cin>>x>>y>>z;
        if(st[x].insert(i).second== true){
            q[x].push_back(i);
            st[x].insert(i);
        }
        if(st[y].insert(i).second== true){
            q[y].push_back(i);
            st[y].insert(i);
        }
        if(st[z].insert(i).second== true){
            q[z].push_back(i);
            st[z].insert(i);
        }
    }
    for (int i = 1; i <=20 ; ++i) {
        sort(q[i].begin(),q[i].end());
    }
    while(1){
        cnt=1;
        cin>>qd;
        if(qd==0)break;
        ::memset(vis,0,sizeof vis);
        vector<vector< int >>ans;
        vector<int >t;
        vis[qd]=1;
        t.push_back(qd);
        dfs(t,qd);
    }
    }

    3.A计划

    思路:此题最大的特点就是两张图,有传送门,刚开始想用dfs实现,但dfs不一定是最短路,且dfs两个图独立。因此用bfs,特判一下能否可以传送即可

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    void solve();
    char mp[3][12][12];
    int vis[3][12][12];
    int n,m,t;
    struct node{
    int x,y,z,t;
    };
    int dx[4]={-1,1,0,0};
    int dy[4]={0,0,-1,1};
    int bfs(){
    vis[1][1][1]=1;
    queue<node>q;
    q.push({1,1,1,0});
    while(q.size()){
        auto a=q.front();
        q.pop();
        node b;
        for (int i = 0; i < 4; ++i) {
            b.x=a.x+dx[i];
            b.y=a.y+dy[i];
            b.z=a.z;
            b.t=a.t+1;
            if(b.t>t){
                return -1;
            }
            if(mp[b.z][b.x][b.y]=='#'){
                if(b.z==1){
                    b.z=2;
                }
                else b.z=1;
            }
            if(b.x<1||b.x>n||b.y<1||b.y>m||mp[b.z][b.x][b.y]=='*'||vis[b.z][b.x][b.y]==1||mp[b.z][b.x][b.y]=='#')
                continue;
            else{
                vis[b.z][b.x][b.y]=1;
                q.push(b);
                if(mp[b.z][b.x][b.y]=='P'){
                    return b.t;
                }
            }
        }
    }
    return -1;
    }
    int main(){
    int whc;
    cin>>whc;
    while(whc--){
        solve();
    }
    }
    void solve(){
    ::memset(vis,0,sizeof vis);
    ::memset(mp,0,sizeof mp);
    cin>>n>>m>>t;
    for (int i = 1; i <=2 ; ++i) {
        for (int j = 1; j <=n ; ++j) {
            scanf("%s",mp[i][j]+1);
        }
    }
    int time=bfs();
    if(time!=-1){
        cout<<"YES\n";
    }
    else{
        cout<<"NO\n";
    }
    }

    4.Eight.八数码问题(easy.version)

    思路:我们反向的想,先算从初始状态“12345678x”可以形成哪些状态,因为我们是反向来看的,因此我们从上一个状态到下一个状态若是左,那么我们记录的便是右,相反记录即可,关键一点是这张图的位置我们可以映射为x=i/3,y=i%3,用unordered_map来存每一个状态所需的路径,然后我们return一下,便是答案,查询复杂度是O(1);

    不懂的点:G++MLT了,C++AC了

    代码:

    #include<iostream>
    #include<vector>
    #include<queue>
    #include<string>
    #include<unordered_map>
    #include <algorithm>
    using namespace std;
    #define int long long
    #define  PII pair<int,int>
    const int N=1e3+10;
    string res="12345678x",s(9,0);
    unordered_map<string ,string >vis;
    int dx[4]={-1,1,0,0};
    int dy[4]={0,0,-1,1};
    string dir="durl";
    void bfs(){
     queue<string >q;
     q.push(res);
     while(!q.empty()){
         string t=q.front();
         q.pop();
         int u=t.find('x');
         int x=u/3;
         int y=u%3;
         string dist=vis[t];
         for (int i = 0; i <4 ; ++i) {
             int a=x+dx[i],b=y+dy[i];
             if(0<=a&&a<3&&b>=0&&b<3){
                 swap(t[u],t[a*3+b]);
                 if(!vis.count(t)){
                     vis[t]=dist+dir[i];
                     q.push(t);
                 }
                 swap(t[u],t[a*3+b]);
             }
         }
     }
    }
    signed main(){
    bfs();
    while(cin>>s[0]){
        for (int i = 1; i <9 ; ++i) {
            cin>>s[i];
        }
        if(vis.count(s)){
            string ans=vis[s];
            reverse(ans.begin(),ans.end());
            cout<<ans<<endl;
        }
        else{
            cout<<"unsolvable\n";
        }
    }
    }
posted on 2023-05-06 18:47  IR101  阅读(2)  评论(0编辑  收藏  举报  来源