其他分享
首页 > 其他分享> > 【搜索】AcWing 184. 虫食算

【搜索】AcWing 184. 虫食算

作者:互联网

写完发现代码比别人的都长(悲

但是效率不错,在洛谷可以排在最优解第四页

分析

大致思路比较简单:

接下来考虑剪枝:

实现

// Problem: 虫食算
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/186/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;

#define debug(x) cerr << #x << ": " << (x) << endl
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
#define all(x) (x).begin(), (x).end()

#define x first
#define y second
using pii = pair<int, int>;
using ll = long long;

inline void read(int &x){
    int s=0; x=1;
    char ch=getchar();
    while(ch<'0' || ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0' && ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

const int N=30;

int n;
string a, b, c;
int res[N];
int det;

int lowbit(int x){
    return x&-x;
}

void get(vector<int> &d){
    int t=det;
    while(t) d.pb(__lg(lowbit(t))), t-=lowbit(t);
}

bool ng(){
    rep(u,0,n-1){
        int x=res[a[u]-'A'];
        int y=res[b[u]-'A'];
        int z=res[c[u]-'A'];
        if(~x && ~y && ~z){
            if((x+y)%n!=z && (x+y+1)%n!=z){
                return true;
            }
        }
    }
    return false;
}

bool dfs(int u, int carry){
    if(u==n){
        return (!carry);
    }
    if(ng()) return false;

    vector<int> fir, sec;
    int pre1=res[a[u]-'A'], pre2=res[b[u]-'A'];
    if(~pre1) fir.pb(res[a[u]-'A']);
    else get(fir);
    if(~pre2) sec.pb(res[b[u]-'A']);
    else get(sec);

    if(a[u]==b[u]){
        reverse(all(fir));
        for(auto i: fir){
            res[a[u]-'A']=i;
            det^=(1<<i);

            int t=i+i+carry;
            int pre3=res[c[u]-'A'];
            if(~pre3){
                if(t%n!=pre3){
                    det^=(1<<i);
                    continue;
                }
            }
            else{
                int val=t%n;
                if(!(det&(1<<val))){
                    det^=(1<<i);
                    continue;
                }
                res[c[u]-'A']=val;
            }

            if(dfs(u+1, t/n)) return true;

            det^=(1<<i);
            res[c[u]-'A']=pre3;
        }
    }
    else{
        reverse(all(fir));
        reverse(all(sec));
        for(auto i: fir) for(auto j: sec) if(i!=j){
            res[a[u]-'A']=i;
            res[b[u]-'A']=j;
            det^=(1<<i);
            det^=(1<<j);
            int t=i+j+carry;
            int pre3=res[c[u]-'A'];
            if(~pre3){
                if(t%n!=pre3){
                    det^=(1<<i);
                    det^=(1<<j);
                    continue;
                }
            }
            else{
                int val=t%n;
                if(!(det&(1<<val))){
                    det^=(1<<i);
                    det^=(1<<j);
                    continue;
                }
                res[c[u]-'A']=val;
            }

            if(dfs(u+1, t/n)) return true;

            det^=(1<<i);
            det^=(1<<j);
            res[c[u]-'A']=pre3;
        }
    }

    res[a[u]-'A']=pre1;
    res[b[u]-'A']=pre2;
    return false;
}

int main(){
    cin>>n>>a>>b>>c;
    reverse(all(a));
    reverse(all(b));
    reverse(all(c));

    det=(1<<n)-1;
    memset(res, -1, sizeof res);
    dfs(0, 0);

    rep(i,0,n-1) cout<<res[i]<<' ';

    return 0;
}

标签:fir,ch,return,食算,res,int,184,define,AcWing
来源: https://www.cnblogs.com/Tenshi/p/16419303.html