题面描述:可以跳过

一个形如:

X1X2…Xn=Y1Y2..Ym

的等式称为二进制方程。

在二进制方程的两边:Xi和Yj (1<=i<=n;1<=j<=m)是二进制数字(0、1)或者一个变量(小写字母)。每个变量都是一个有固定长度的二进制代码,他可以在等式中取代变量的位置,称这个长度为变量的长度。为了解一个二进制方程,需要给其中的变量赋予适当的二进制代码,使得我们用他们替代等式中的相应的变量后(等式的两边都变成二进制代码),这个等式成立。

编程任务:

对于每一个给出的方程,计算一共有多少组解。已知变量最多有26个(26个英文小写字母),且等式的每一端的数字和变量的长度之和不超过10000。

输入格式

第一行:k(k<=26,变量的个数,规定使用小写英文字母中的前k个字母作为变量,如k=5,则变量a,b,c,d,e)。

第二行:k个正整数,中间用一个空格隔开,依次代表k个变量的长度。

第三行:等式左边的表达式。

第四行:等式右边的表达式。

输出格式

等式中出现的变量共有多少组解。

输入输出样例

输入 #1

2
4 2
1b1
a
输出 #1

4
输入 #2

5
4 2 4 4 2
1bad1
acbe
输出 #2

16

说明/提示

样例一:4组解

1 、a=1001; b=00

2、 a=1011; b=01

3、 a=1101; b=10

4、 a=1111; b=11)

样例二:K=5,变量:a,b,c,d,e。长度分别为:4 2 4 4 2。等式是:1bad1= acbe

输出16,即变量a,b,c,d,e共有16组解。

(为什么复制按钮还能粘贴上??(雾))


正解开始:

首先读懂题意我们知道,每一个字母都代表一个式子,且把每一个字母替换成数字后可以使得左右两个式子相等。

本人思路来源:先进行过样例式的枚举:

考虑这种情况:假如左边式子第1位是a,右边式子第一位是1,一个数字,一个字母,因为题意要满足对应位相等,所以我们可以确定字母a的第一位为1。但是,因为整个字符串中maybe有多个a,那么我们找到字符串中的其他的a,把它们第一位对应的位数赋值为1.

然而a的第一位的对应位确定,那么等号另一边的对应位也能确定了,而它又是一个字母,于是我们把这个字母的对应位也找出来进行赋值。。。。。。这么下去,解法逐渐明朗:并查集。

具体来说,我们可以按照这种方法,把所有的能遍历到的位置按照并查集处理,并看做一种情况。最后,看还剩几种情况,我们把答案高精度乘为2的几次方就OK了(因为每一位有0,1两种方法)qwq。

code:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=; int n,m,k,sum;
int num[maxn],fa[maxn],x[maxn],y[maxn]; inline int find(int x)
{
if(x==fa[x])return x;
fa[x]=find(fa[x]);
return fa[x];
} int main() {
num[]=;
scanf("%d",&k);
for(int i=,x;i<=k+;++i)
{
scanf("%d",&x);
num[i]=num[i-]+x;
sum+=x;//记录总不同的个数
}
char zfc[maxn];
scanf("%s",zfc);
for(int i=;zfc[i];++i)
{
if(zfc[i]>='a'&&zfc[i]<='z')
{
int c=zfc[i]-'a'+;//获取他是num数组第几个
for(int j=num[c];j<num[c+];++j)x[++n]=j;//按位置赋值
}
else x[++n]=zfc[i]-'';//数字的话
}
scanf("%s",zfc);
for(int i=;zfc[i];++i)
{
if(zfc[i]>='a'&&zfc[i]<='z')
{
int c=zfc[i]-'a'+;
for(int j=num[c];j<num[c+];++j)y[++m]=j;//字母
} else y[++m]=zfc[i]-'';//数字
}
if(n!=m)//连左右长度都不相等
{
printf("");return ;//直接输出零
}
for(int i=;i<maxn;++i)fa[i]=i;//初始化并查集找父亲
for(int i=;i<=n;++i)
{
int dx=find(x[i]),dy=find(y[i]);
if(dx+dy==)
{
printf("");
return ;
}
if(dx!=dy)
{
fa[max(dx,dy)]=min(dx,dy);
sum--;
}
}
int big[maxn]={},top=;
for(int i=sum;i>=;i--)
{
for(int i=;i<top;++i)big[i]<<=;
for(int i=;i<top;++i)if(big[i]>=) {
big[i+]+=big[i]/,big[i]%=;
}
for(;big[top];++top) {
big[top+]+=big[top]/,big[top]%=;
}
}
for(int i=top-;i>=;--i) printf("%d",big[i]);
return ;
}

完结qwq

p2456二进制方程 题解的更多相关文章

  1. 洛谷P2456 二进制方程

    题目 字符串模拟+并查集 建立两个并查集分别存放每个变量的每一位数的祖先,一个是1一个是2 考虑每个字母的每一位的数都是唯一的,先模拟,记录每一个变量的每一位. 一一映射到方程中去,最后将两个方程进行 ...

  2. Luogu p2456 二进制方程

    这是一道我也不知道我gu了多久的题目 (然鹅还有n多任务没有完成) 反正--我太难了 好了言归正传,题目链接 是一道校内测的题目(现在应该没有人没考了吧?) 思路的话,是神仙并查集√ 觉得虽然并查集很 ...

  3. P2456 [SDOI2006]二进制方程

    P2456 [SDOI2006]二进制方程 题解 拿个样例模拟一下发现 把等式两边对应展开,每个位置的填数都是一一对应的 比如第二个样例 分类讨论: (1)xi  yi  都是数字,但是不相同,此时无 ...

  4. 洛谷P2312 解方程题解

    洛谷P2312 解方程题解 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 \([1,m]\) 内的整数解(\(n\) 和 \(m\) ...

  5. 洛谷 P2312 解方程 题解

    P2312 解方程 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 [1,m][1,m] 内的整数解(\(n\) 和 \(m\) 均为 ...

  6. [SDOI2006] 二进制方程

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

  7. 洛谷P2312解方程题解

    题目 暴力能得\(30\),正解需要其他的算法操作,算法操作就是用秦九韶算法来优化. 秦九韶算法就是求多项式的值时,首先计算最内层括号内一次多项式的值,然后由内向外逐层计算一次多项式的值,然后就将求\ ...

  8. 2019.11.11&12题解

    Day1 考的不是很好,T1T2没区分度,T3想的太少,考试后期几乎都是在摸鱼,bitset乱搞也不敢打,只拿到了35分,跟前面的差距很大 A. 最大或 标签: 二进制+贪心 题解: 首先x,y中一定 ...

  9. 【USACO 3.2】Stringsobits (dp)

    题意:求第k大的最多有l个1的n位二进制. 题解:dp[i][j]表示长度为i最多有j个1的二进制有多少种,则有: 状态转移:dp[i][j]=dp[i-1][j]+dp[i-1][j-1],即第i位 ...

随机推荐

  1. 学习笔记:CentOS7学习之十三(1):硬盘介绍

    1. SAS-SATA-SSD-SCSI-IDE硬盘讲解 1.1 常见硬盘类型: SAS硬盘:SAS(Serial Attached SCSI),串行连接SCSI接口,串行连接小型计算机系统接口.SA ...

  2. 从ftp服务器进行批量下载,处理文件名保存时重名的问题,更改重名文件名方式为给后面加1、2、3等数字,保持后缀不变

    公司最近有一个从ftp批量下载文件的需求,但是文件名重复总会报错 没办法,自己下班后写了一个小算法 仿照桶排序的原理,实现了这个小功能,直接上代码: String[] test = {"ha ...

  3. WijmoJS 中自定义 React 菜单和列表项模板

    WijmoJS 中自定义 React 菜单和列表项模板 在V2019.0 Update2 的全新版本中,React 框架下 WijmoJS 的前端UI组件功能再度增强. WijmoJS的菜单和类似列表 ...

  4. 【深入浅出-JVM】(2):原码、反码、补码

    计算机中有补码表示 0 0 为正数 原码 00000000 00000000 00000000 00000000 反码 00000000 00000000 00000000 00000000 正数反码 ...

  5. # Python 3 & 爬虫一些记录

    目录 Python 3 & 爬虫一些记录 交互模式和命令行模式 函数积累 语法积累 列表和元组 输入 交互模式下输入多行 爬虫 HTTP报文请求头User-Agent信息 解析库pyquery ...

  6. 在 jupyterlab 和 jupyter notebook 中集成conda虚拟环境

    在jupyterlab中切换虚拟环境使用jupyter-conda包,参考链接:https://pypi.org/project/jupyter-conda/ Install Requirements ...

  7. 安装kubenetes-遇到的问题总结

    # 5.修改docker的cgroup驱动(不需要操作)# kubelet# 看到最后一行:error: failed to run Kubelet: failed to create kubelet ...

  8. Spring实战(八)bean装配的运行时值注入——属性占位符和SpEL

    前面涉及到依赖注入,我们一般哦都是将一个bean引用注入到另一个bean 的属性or构造器参数or Setter参数,即将为一个对象与另一个对象进行关联. bean装配的另一个方面是指将一个值注入到b ...

  9. Java 面向对象的设计原则

    一. 1.面向对象思想的核心: 封装.继承.多态.   2.面向对象编程的追求: 高内聚低耦合的解决方案: 代码的模块化设计: 3.什么是设计模式: 针对反复出现的问题的经典解决方案,是对特定条件下( ...

  10. 怎样终止(杀掉) Linux 中的进程?

    使用 kill -9 进程号 命令, 可是强行终止该进程. 如果使用直接使用 kill 进程号 命令, 则会让进程 "自行了断" . 因此, 一般是 kill -9 进程号 用得较 ...