• P1092虫食算题解


    2018-10-24

    题目链接

    题目思路:

    我就讲下剪枝操作吧。

    三个式子从上到下为A,B,C

    剪枝操作

    1.从3个式子右边开始从上到下枚举字母对应数字。(搜索顺序关键)

    2.末尾(A+B)%n!=C。

    3.已知A,B,不知C,且C的可能数字已经使用。(这三个点从2000ms)

    4.已知A.C,不知B,且B的可能数字已经使用。(一下剪枝成)

    5.已知B,C,不知A,且A的可能数字已经使用。(100ms)

    6.已知A,B,C,且A+B不等于C,且A+B+1不等于C。

    7.已经A,B,C的最高位,且A+B有进位

    8.逆序枚举数字。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<map>
    #define R register
    using namespace std;
    const int N=30;
    int n,dis[N],flag[N],num,mp2[N];
    char a[N],b[N],c[N],mp1[N];
    inline int read(){ 
     R int s=0,w=1;R char ch=getchar();
     while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} 
     while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
     return s*w;
    }
    inline void write(R int x) {
        if(x < 0) {
            putchar('-');
            x = -x;
        }
        if(x >= 10) write(x / 10);
        putchar(x % 10 + '0');
    }
    inline int judge(){
            R int cnt=0;
            R int q=0,e=0,x=0;
            R int ss[N];
            for(R int i=n-1;i>=0;--i){
                  ++cnt;
                  ss[n-i-1]=x+dis[mp2[a[i]&31]]+dis[mp2[b[i]&31]];
                  x=ss[n-i-1]/n;
                  ss[n-i-1]%=n;
            }
            if(x)return 0;
            for(R int i=0;i<=n-1;++i)q=(q<<1)*5+ss[i];
            for(R int i=0;i<=n-1;++i)e=(e<<1)*5+dis[mp2[c[n-i-1]&31]];
            if(e==q)return 1;
            return 0;
    }
    inline int jianzhi(){
          if(dis[mp2[a[n-1]&31]]!=-1&&dis[mp2[b[n-1]&31]]!=-1&&dis[mp2[c[n-1]&31]]!=-1&&(dis[mp2[a[n-1]&31]]+dis[mp2[b[n-1]&31]])%n!=dis[mp2[c[n-1]&31]])return 1;
          if((dis[mp2[a[0]&31]]!=-1)&&(dis[mp2[b[0]&31]]!=-1)&&(dis[mp2[a[0]&31]]+dis[mp2[b[0]&31]]>=n))return 1;
            for(R int i=n-1;i>=0;--i){
                    if((dis[mp2[a[i]&31]]!=-1)&&(dis[mp2[b[i]&31]]!=-1)&&(dis[mp2[c[i]&31]]==-1)&&(flag[(dis[mp2[a[i]&31]]+dis[mp2[b[i]&31]])%n]==1&&flag[(dis[mp2[a[i]&31]]+dis[mp2[b[i]&31]]+1)%n]==1))return 1;
               if((dis[mp2[a[i]&31]]!=-1)&&((dis[mp2[c[i]&31]]!=-1))&&(dis[mp2[b[i]&31]]==-1)&&flag[(dis[mp2[c[i]&31]]-dis[mp2[a[i]&31]]+n)%n]&&flag[(dis[mp2[c[i]&31]]-dis[mp2[a[i]&31]]-1+n)%n])return 1;
               if((dis[mp2[b[i]&31]]!=-1)&&((dis[mp2[c[i]&31]]!=-1))&&(dis[mp2[a[i]&31]]==-1)&&(flag[(dis[mp2[c[i]&31]]-dis[mp2[b[i]&31]]+n)%n])&&(flag[(dis[mp2[c[i]&31]]-dis[mp2[b[i]&31]]-1+n)%n]))return 1;
            if(dis[mp2[a[i]&31]]!=-1&&dis[mp2[b[i]&31]]!=-1&&dis[mp2[c[i]&31]]!=-1){
    if((((dis[mp2[a[i]&31]]+dis[mp2[b[i]&31]])%n)!=dis[mp2[c[i]&31]])&&(((dis[mp2[a[i]&31]]+dis[mp2[b[i]&31]]+1)%n)!=dis[mp2[c[i]&31]]))return 1;         
            }
            }
            return 0;
    }
    void dfs(R int pos){
            if(jianzhi())return;
            if(pos==n+1){        
                if(judge()){
                for(R int i='A';i<='A'+n-1;++i){
                write(dis[mp2[i&31]]);
                printf(" ");
                }
                exit(0);
                }
                return;
            }
            for(R int i=n-1;i>=0;--i){
                if(!flag[i]){
                dis[pos]=i;flag[i]=1;
                dfs(pos+1);
                dis[pos]=-1;flag[i]=0;
                }
            }
    }
    int main(){
          memset(dis,-1,sizeof(dis));
            n=read();scanf("%s",a);
            scanf("%s",b);scanf("%s",c);
            for(R int i=n-1;i>=0;--i){
                  if(mp2[a[i]&31]==0){
                    ++num;
                    mp2[(a[i]&31)]=num;
                    mp1[num]=a[i];
                }
                      if(mp2[c[i]&31]==0){
                      ++num;
                    mp2[(c[i]&31)]=num;
                    mp1[num]=c[i];
                }
                      if(mp2[b[i]&31]==0){
                    ++num;
                    mp2[(b[i]&31)]=num;
                    mp1[num]=b[i];
                }
            }
            for(R int i=n-1;i>=0;--i){
            dis[1]=i;flag[i]=1;
            dfs(2);
            dis[1]=-1;flag[i]=0;
            }
            return 0;
    }
  • 相关阅读:
    前端工具Rythem介绍
    Redis持久化————AOF与RDB模式
    Hessian——轻量级远程调用方案
    JavaScript中的类数组对象
    在SpringMVC中获取request对象
    linux下,远程连接mysql
    nohup后台运行jar与关闭
    Vi常用命令
    spring mvc 重定向问题
    eclipse修改jdk后版本冲突问题
  • 原文地址:https://www.cnblogs.com/sky-zxz/p/9841117.html
Copyright © 2020-2023  润新知