• P2456 [SDOI2006]二进制方程


    P2456 [SDOI2006]二进制方程

    题解

    拿个样例模拟一下发现

    把等式两边对应展开,每个位置的填数都是一一对应的

    比如第二个样例

    分类讨论:

    (1)xi  yi  都是数字,但是不相同,此时无解

    (2)xi  yi  都是数字,相同,唯一填法

    (3)xi  yi  一个是数字,一个是字母,唯一填法

    (4)xi  yi  都是字母,颜色不同,那么一旦在该颜色对应的位置上填了一个数字,对应的另一种颜色,或者是该颜色在其他区域的对应位置也填上了这个数字

           所以我们就把同一种颜色的方块用并查集联系起来

    解释代码:

    (1)num[ ] 给0,1,每一个字母每一个位置都有唯一的编号,num[ i ]记录第 i 种字母的最后一个位置在哪里,但是实际应用起来就是下表对应的亚子:

     

    这么做是方便以后的并查集

     (2)sum记录多少个待确定的位置(也就是有两种填法),答案其实是 2待确定位置数

     (3)x[ ] y[ ] 记录展开后的式子

     (4)判断无解,1是x[  ] y[  ]长度不一样,2是 xi  yi 的祖先一个是1 一个是0

     (5)取最大的一个的父亲是最小的一个

     (6)高精度

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<string>
    #include<cstring>
    #include<cstdlib>
    #include<queue>
    
    using namespace std;
    
    inline int read()
    {
        int ans=0;
        char last=' ',ch=getchar();
        while(ch<'0'||ch>'9') last=ch,ch=getchar();
        while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
        if(last=='-') ans=-ans;
        return ans;
    }
    
    int num[28],x[10010],y[10010],fa[100010],sum=0,t1=0,t2=0,k;
    char s[10010];
    int c[1000010],lenc;
    
    int find(int x)
    {
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    
    void cheng()
    {
        c[0]*=2;
        for(int i=1;i<lenc;i++)
        {
            c[i]=c[i]*2+c[i-1]/10;
            c[i-1]%=10;
        }
        while(c[lenc-1]>=10)
        {
            c[lenc]=c[lenc-1]/10;
            c[lenc-1]%=10;
            lenc++;
        }
    }
    
    int main()
    {
        k=read();
        num[1]=2;  //解释1 
        for(int i=2,u;i<=k+1;i++)
        {
            u=read();
            num[i]=num[i-1]+u;
            sum+=u;  //解释2 
        }
        scanf("%s",s);
        int len=strlen(s);
        for(int i=0;i<len;i++)
        {
            if(s[i]>='a'&&s[i]<='z')
            {
                int v=s[i]-'a'+1;
                for(int j=num[v];j<num[v+1];j++) x[++t1]=j;
            } 
            else x[++t1]=s[i]-'0';
        }
        scanf("%s",s);
        len=strlen(s);
        for(int i=0;i<len;i++)
        {
            if(s[i]>='a'&&s[i]<='z')
            {
                int v=s[i]-'a'+1;
                for(int j=num[v];j<num[v+1];j++) y[++t2]=j;
            } 
            else y[++t2]=s[i]-'0';
        }
        
        if(t1!=t2){ printf("0
    ");return 0; }  //无解判断 
        
        for(int i=0;i<=num[k+1];i++) fa[i]=i;
        
        for(int i=1;i<=t1;i++)
        {
            int f1=find(x[i]),f2=find(y[i]);
            if(f1+f2==1) { printf("0
    ");return 0; } //解释4 
            if(f1!=f2)
            {
                fa[max(f1,f2)]=min(f1,f2);  //解释5 
                sum--; //少了一个可以填两种方案的 
            }
        }
        
        c[0]=1;lenc=1;
        for(int i=sum;i>=1;i--)
          cheng();  //解释6 
        for(int i=lenc-1;i>=0;i--)
          printf("%d",c[i]);
        
        return 0;
    }
  • 相关阅读:
    Dragonfly 基于 P2P 的文件和镜像分发系统
    一文搞懂 SAE 日志采集架构
    携手共建云原生生态 阿里云云原生加速器第二次集结圆满结营
    开放下载 | 飞天技术峰会云原生加速应用构建分论坛资料开放下载
    使用函数计算自定义运行时快速部署一个 SpringBoot 项目 | 文末有礼
    阿里云容器服务 ACK 产品技术动态(202207)
    阿里云 ACK One 多集群管理全面升级:多集群服务、多集群监控、两地三中心应用容灾
    掌握软件开发技术的第一性原理2
    掌握软件开发技术的第一性原理1
    library
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11385780.html
Copyright © 2020-2023  润新知