zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    linq查询结果指定列的两种方式
    MVC HTML辅助类常用方法记录
    如何获取google地图、baidu百度地图的坐标
    js解析Json字符串的方法
    EF 官方API
    sqlserver 计算 百分比
    js 判断js函数、变量是否存在
    JS 去字符串空格 总结
    sql 转换日期格式 只保留月份和日期
    C# json object互转工具
  • 原文地址:https://www.cnblogs.com/sky-zxz/p/9841117.html
Copyright © 2011-2022 走看看