代码等式
来源:互联网 发布:adobe cc 2017 mac破解 编辑:程序博客网 时间:2024/04/27 20:27
Description
有一个二进制码。不过你得到的是“加密”的代码,有几个连续的数字(0或1)合为了一个长度一定的变量,你得到了两条本来相同加密方式不同的代码(代码中包含变量)以及变量的长度,求原代码可能的个数。
Input
第一行一个正整数T(1<=T<=2)表示共有T组数据每组数据输入共6行:第一行一个正整数n(0<=n<=26),表示变量的个数(变量用abcdefg..这样连续的小写英文表示)第二行一共n个正整数(X1,X2,X3...),每一个数字Xi(0<=Xi<=10000)表示一个变量的长度(X1表示变量a的长度;X2表示变量b的长度;X3表示变量c的长度...)第三行一个正整数length1(1<=lenght1<=5000),表示第一条代码的长度第四行一个长度为length1的字符串,表示第一条代码第五行一个正整数length2(1<=length2<=5000),表示第二条代码的长度第六行一个长度为length2的字符串,表示第二条代码
Output
共T行,每一行一个整数,表示原代码可能的个数
Sample Input
154 2 4 4 251bad14acbe
Sample Output
16
分析
我们把式子打开,得到“a1a21b1b2”,“b1b2c1c2c3”,题目要求是对应位置上的相等。我们可以把每个元素看做一个点,在对应位置上的连一条边(比如a1和b1有一条边,1和c1有一条边),那么可以形成一些联通块,每个联通块互不影响,所以答案就是2^p(p是联通块个数,不过不能算那些包含0或者是1的联通块),因为每一个联通块里都可以是0或者是1(不包括那些包含0或者是1联通块)故由乘法原理我们可以知道答案就是2^p.
代码
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int a[27][10010];int fa[274700];int n;int len[27];char str1[4700];int len1;char str2[4700];int tmp[470000];int len2;int r;int ans[470000];int k;int tot;int fin(int);void uni(int,int);void mi(int);int main(){ scanf("%d",&r); while(r--){ scanf("%d",&n); for(int i=0;i<n;++i) scanf("%d",len+i); scanf("%d%s%d%s",&len1,str1,&len2,str2); int len_tr = 0; for(int i=0;i<len1;++i) if(str1[i]=='0' || str1[i]=='1') ++len_tr; else len_tr += len[str1[i]-'a']; for(int i=0;i<len2;++i) if(str2[i]=='0' || str2[i]=='1') --len_tr; else len_tr -= len[str2[i]-'a']; if(len_tr){ printf("0\n"); goto go_next_loop; } tot = 1; for(int i=0;i<n;++i) for(int j=1;j<=len[i];++j) a[i][j] = ++tot; for(int i=0;i<=tot;++i) fa[i] = i; for(int i=0,x=0,y=1,p=0,q=1;x<len1&&p<len2;++i){ if(str1[x]==str2[p] && (str1[x]=='0'||str1[x]=='1')){ x++,p++,y=q=1; continue; } else if((str1[x]=='0'&&str2[p]=='1') || (str1[x]=='1'&&str2[p]=='0')){ printf("0\n"); goto go_next_loop; } else if(str1[x]=='0' || str1[x]=='1'){ uni(str1[x]-'0',a[str2[p]-'a'][q]); x++,y=1,q++; } else if(str2[p]=='0' || str2[p]=='1'){ uni(str2[p]-'0',a[str1[x]-'a'][y]); p++,q=1,y++; } else{ uni(a[str1[x]-'a'][y],a[str2[p]-'a'][q]); y++,q++; } if(y > len[str1[x]-'a']) x++,y=1; if(q > len[str2[p]-'a']) p++,q=1; } if(fin(0) == fin(1)){ printf("0\n"); goto go_next_loop; } k = 0; for(int i=0;i<=tot;++i) if(fa[i] == i) ++k; memset(ans,0,sizeof ans); mi(k-2); for(int i=ans[0];i>=1;--i) printf("%d",ans[i]); putchar(10); go_next_loop:; } return 0;}int fin(int x){ int r = x,q; while(r != fa[r]) r = fa[r]; while(x != fa[x]){ q = fa[x]; fa[x] = r; x = q; } return r;}void uni(int x,int y){ fa[fin(x)] = fin(y);}void mi(int p){ if(p == 1){ ans[0] = 1; ans[1] = 2; return ; } if(p == 0){ ans[0] = 1; ans[1] = 1; return ; } mi(p/2); memset(tmp,0,sizeof tmp); for(int i=1;i<=ans[0];++i) for(int j=1;j<=ans[0];++j) tmp[i+j-1] += ans[i]*ans[j]; if(p&1) for(int i=1;i<=(ans[0]<<1)-1;++i) tmp[i] <<= 1; for(int i=2;i<=(ans[0]<<1);++i){ tmp[i] += tmp[i-1]/10; tmp[i-1] %= 10; } ans[0] <<= 1; if(!tmp[ans[0]]) ans[0] -= 1; for(int i=1;i<=ans[0];++i) ans[i] = tmp[i];}
0 0
- 代码等式
- 代码等式
- 1138 代码等式[C]
- POI代码等式
- 代码等式[POI]
- 等式
- SCAU 1138 代码等式 并查集
- 并查集经典题_代码等式_spoj179
- scau 1138 代码等式 ( 并查集 )
- 等式问题
- 经典等式
- 等式问题
- mod等式
- 除法等式
- 等式变换
- 求等式
- 等式数量
- 等式变换
- HDU 5612:Baby Ming and Matrix games 分数模板
- mfs 连接频繁断开
- db2中获取某个表/索引占用空间的大小
- Android设计模式-面向对象的六大原则
- 设计模式之单例模式
- 代码等式
- (Repeating Decimals) uva 202 需要一些灵感。。。
- 输入输出流、模板
- Educational Codeforces Round 6 C. Pearls in a Row(贪心)
- expect
- python序列通用操作符
- DP------Climbing Stairs
- hbase的rowkey简单设计
- python3.5模拟登陆