虫食算

来源:互联网 发布:知乎每周精选 订阅 编辑:程序博客网 时间:2024/05/16 15:52

这个题很6啊
字符串处理很恶心啊,在我调了两个晚自习之后终于a了
思路:枚举每一个数字代表哪一个字母,如果是30分,就是一个全排列啊,找出所有排列前情况,暴力判断是否过
而这样显然,26的阶乘会炸的很惨,所以我们就需要很多优化
1.如果一竖行的都算出来了,直接判断是否正确,就不用枚举下面的了
2.如果第一位的加起来大于等于n了,就要进位了,这是不符合题意的
3.按从后往前的的顺序搜,先枚举最后的,一排一排的枚举,找出一个序列,这样可以使1优化和更优

#include<cstdio>#include<iostream>#include<cmath>#include<cstring>#include<stdlib.h>using namespace std;int n,ff[999];int z[999], b[399];char w[399];char a[399],c[399];int pos[999],cnt,s[999]; int add(){    memset(z,0,sizeof(z));    for(int i=n-1;i>=0;i--)    {        z[i]+=b[a[i]-'A']+b[c[i]-'A'];        z[i-1]+=z[i]/n;        z[i]%=n;    }    for(int i=0;i<n;i++)    if(z[i]!=b[w[i]-'A']) return 0;    return 1;}bool check1(){    for(int i=n-1;i>=0;i--)     if(b[a[i]-'A']!=-1&&b[c[i]-'A']!=-1&&b[w[i]-'A']!=-1)      if(((b[a[i]-'A']+b[c[i]-'A'])%n!=b[w[i]-'A'])&&((b[a[i]-'A']+b[c[i]-'A']+1)%n!=b[w[i]-'A']))       return 0;     return 1;}void dfs(int ww){    if(b[a[0]-'A']+b[c[0]-'A']>n-1)return ;    if(!check1())return ;    if(ww==n)    {        if(add())        {        for(int i=0;i<n;i++)        printf("%d ",b[i]);        exit(0);        }        return ;    }    for(int i=n-1;i>=0;i--)    {        if(!ff[i])        {            b[pos[ww]]=i;            ff[i]=1;            dfs(ww+1);            ff[i]=0;            b[pos[ww]]=-1;        }    }}int main(){    scanf("%d",&n);    for(int i=0;i<=n;i++) b[i]=-1;    for(int i=0;i<n;i++)cin>>a[i];    for(int i=0;i<n;i++)cin>>c[i];    for(int i=0;i<n;i++)cin>>w[i];    for(int i=n-1;i>=0;i--){        if(!s[a[i]-'A'])        {            pos[cnt++]=a[i]-'A';            s[a[i]-'A']=1;        }        if(!s[c[i]-'A'])        {            pos[cnt++]=c[i]-'A';            s[c[i]-'A']=1;        }        if(!s[w[i]-'A'])        {            pos[cnt++]=w[i]-'A';            s[w[i]-'A']=1;        }        if(cnt==n)break;    }    dfs(0);     return 0;}
原创粉丝点击