[SDOI2006] 二进制方程

Posted nosta

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SDOI2006] 二进制方程相关的知识,希望对你有一定的参考价值。

并查集水题。维护变量的对应位的相关关系,判断不确定点(自由元)的个数即可。
代码中的p数组:p[1] 值的id, p[2~k+1]每个变量的第一位的id。

#include <bits/stdc++.h>
using namespace std;
const int N=1e4+7;

int n,m,k,tot;
int p[N],fa[N],x[N],y[N];

int get(int x) {return fa[x]==x? x: fa[x]=get(fa[x]);}

int main() {
    p[1]=2; 
    scanf("%d",&k);
    for(int i=2,x; i<=k+1; ++i) {
        scanf("%d",&x);
        p[i]=p[i-1]+x;
        tot+=x;
    }
    
    static char str[N];
    scanf("%s",str);
    for(int i=0; str[i]; ++i) {
        if(isalpha(str[i])) {
            int c=str[i]-'a'+1;
            for(int j=p[c]; j<p[c+1]; ++j) x[++n]=j;
        } else x[++n]=str[i]-'0';
    }
    scanf("%s",str);
    for(int i=0; str[i]; ++i) {
        if(isalpha(str[i])) {
            int c=str[i]-'a'+1;
            for(int j=p[c]; j<p[c+1]; ++j) y[++m]=j;
        } else y[++m]=str[i]-'0';
    }
    
    if(n!=m) {
        puts("0");
        return 0;
    }
    for(int i=1; i<N; ++i) fa[i]=i;
    for(int i=1; i<=n; ++i) {
        int dx=get(x[i]), dy=get(y[i]);
        if(dx+dy==1) {
            puts("0");
            return 0;
        }
        if(dx!=dy) {
            fa[max(dx,dy)]=min(dx,dy);
            tot--;
        }
    }
    
    static int dig[N]={1},top=1;
    while(tot--) {
        for(int i=0; i<top; ++i) dig[i]<<=1;
        for(int i=0; i<top; ++i) if(dig[i]>=10) {
            dig[i+1]+=dig[i]/10, dig[i]%=10;
        }
        for(; dig[top]; ++top) {
            dig[top+1]+=dig[top]/10, dig[top]%=10;
        }
    }
    for(int i=top-1; ~i; --i) printf("%d",dig[i]);
    return 0;
}

以下为输入格式:

第一行:k(k<=26,变量的个数,规定使用小写英文字母中的前k个字母作为变量,如k=5,则变量a,b,c,d,e)。
第二行:k个正整数,中间用一个空格隔开,依次代表k个变量的长度。
第三行:等式左边的表达式。
第四行:等式右边的表达式。

以上是关于[SDOI2006] 二进制方程的主要内容,如果未能解决你的问题,请参考以下文章

[Luogu2455] [SDOI2006]线性方程组

luogu P2455 [SDOI2006]线性方程组 题解

SDOI2006 保安站岗

题解 P2458 [SDOI2006]保安站岗

P2458 [SDOI2006]保安站岗

P2457 [SDOI2006]仓库管理员的烦恼 (费用流)