ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【搜索】AcWing 184. 虫食算

2022-06-28 14:34:27  阅读:111  来源: 互联网

标签:fir ch return 食算 res int 184 define AcWing


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

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

分析

大致思路比较简单:

  • 枚举位(使用 \(dfs\)),从低位开始枚举变量的值,如果没填过就选取 \([0, n-1]\) 中没选取过的值填上。
  • 当前位三个变量都得到值后,检查是否合法。
  • 当全部位都合法输出结果即可。

接下来考虑剪枝:

  • 其实上面那个检查合法可以排除很多情况了。
  • 对整个式子进行一遍扫描,逐位检查是否合法:如果当前位对应的值 \(a,b,c\) 同时不满足 \(a+b=c\) 以及 \(a+b+1=c\)(进位情况),那么一定不合法,停止继续向下搜索。
  • 因为题目要求每个变量对应 \([0,n-1]\) 的一个值,所以整个算式看上去应当是数值的分布比较均匀的。因此,我们可以考虑给每一位的变量赋值的时候按照从大到小的顺序,因为如果按照从小到大枚举很容易将小的数都丢到低位去使得到达失败的概率很大。

实现

// 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有