[NOIP2017模拟]Bovine Genomics
来源:互联网 发布:换手机登陆淘宝账号 编辑:程序博客网 时间:2024/06/06 03:04
题目描述
农夫约翰最近发现他的有些奶牛会画画,刚刚学完小学生物的他立刻开始研究起了这些奶牛的 DNA。
具体的,约翰有 N 头会画画的奶牛,N 头不会画画的奶牛,这些奶牛的 DNA 可以用 M 个字符来描述,每个字符是 A、C、G、T中的一个
比如说以下是 N=3,M=8 的一个示例:
位置: 1 2 3 4 5 6 7 8(哎呀对歪了)
会画画的牛 1: A A T C C C A T
会画画的牛 2: A C T T G C A A
会画画的牛 3: G G T C G C A A
不会画画的牛 1: A C T C C C A G
不会画画的牛 2: A C T C G C A T
不会画画的牛 3: A C T T C C A T
约翰发现,他只需要看[2,5]这个区间的 DNA就可以知道一头牛会不会画画(也就是说,没有一头会画画的牛的这个区间的 DNA是和某一头不会画画的牛的这个区间的 DNA相同的),他相信一头牛是否会画画是由这个区间的 DNA决定的,他称这样的区间为“决定区间”。
现在给你所有牛的 DNA,求最短的决定区间的长度。
输入格式
第一行两个数 N,M(N<=500;M<=500)。
接下来N 行,每行 M个字符,描述 N 头会画画的牛的DNA。
接下来N 行,每行 M个字符,描述 N 头不会画画的牛的 DNA。
输出格式
输出最短的决定区间的长度。
样例数据
输入
3 8
AATCCCAT
ACTTGCAA
GGTCGCAA
ACTCCCAG
ACTCGCAT
ACTTCCAT
输出
4
备注
【数据范围】
40% 的数据:N,M<=100。
100% 的数据:N,M<=500。
分析:数据很小,二分枚举长度,然后在每一只牛的DNA中从头开始截取这么长,把会画画的丢进哈希表,用不会画画的去匹配,如果满足没有一个相同的就返回true,继续二分找更短的;不然依次平移一个字符再次计算,如果到最后都没有满足false,就返回,继续二分找更长的。(hash差不多忘光了,回头写个hash总结吧)
代码:
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#include<queue>#include<set>using namespace std;int getint(){ int sum=0,f=1; char ch; for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar()); if(ch=='-') { f=-1; ch=getchar(); } for(;ch>='0'&&ch<='9';ch=getchar()) sum=(sum<<3)+(sum<<1)+ch-48; return sum*f;}const int N=505;const long long p=31,H=23333;//听说进制用31进制最佳(听说而已),但是23333是质数这是真的!int n,m,ans,tot,hash[H],nxt[N];unsigned long long mi[N],num[N<<1][N],val[N*N];char s[N<<1][N];void prework(){ mi[0]=1; for(int i=1;i<=m+1;++i) mi[i]=mi[i-1]*p; for(int i=1;i<=n*2;++i) for(int j=1;j<=m;++j) num[i][j]=num[i][j-1]*p+s[i][j]-'A'+1;}void insert(unsigned long long x){ int y=x%H; for(int v=hash[y];v;v=nxt[v]) if(val[v]==x) return; nxt[++tot]=hash[y]; hash[y]=tot; val[tot]=x;}bool find(unsigned long long x){ long long y=x%H; for(int v=hash[y];v;v=nxt[v]) if(val[v]==x) return true; return false;}bool check(int len){ unsigned long long x; for(int i=1;i<=m-len+1;++i)//在DNA中依次平移 { memset(hash,0,sizeof(hash)); tot=0; int bz=1; for(int j=1;j<=n;++j)//把会画画的整个一段丢进hash表 { x=num[j][i+len-1]-num[j][i-1]*mi[len]; insert(x); } for(int j=n+1;j<=2*n;++j)//用不会画画的这一段去匹配 { x=num[j][i+len-1]-num[j][i-1]*mi[len]; if(find(x)) { bz=0; break; } } if(bz) return true; } return false;}int main(){ freopen("cownomics.in","r",stdin); freopen("cownomics.out","w",stdout); int len; unsigned long long x; n=getint();m=getint(); for(int i=1;i<=n*2;++i) scanf("%s",s[i]+1); prework(); int l=1,r=m; while(l<=r)//二分查找 { int mid=l+r>>1; if(check(mid)) r=mid-1; else l=mid+1; } cout<<l<<endl; return 0;}
本题结
- [NOIP2017模拟]Bovine Genomics
- Bovine Genomics
- Bovine Genomics
- USACO——Bovine Genomics
- [Usaco2017 Open]Bovine Genomics //Trie
- BZOJ 4782 Usaco2017 Open Bovine Genomics
- BZOJ 4779 Usaco2017 Open Bovine Genomics Trie树
- NOIP2017模拟赛1
- NOIP2017模拟赛8
- NOIP2017模拟赛9
- [NOIP2017模拟]切蛋糕
- [NOIP2017模拟]随机图
- [NOIP2017模拟]能源
- [NOIP2017模拟]电影
- [NOIP2017模拟]鸭舌
- [NOIP2017模拟]permut
- [NOIP2017模拟]beautiful
- [NOIP2017模拟]路径
- React-Native学习总结
- Android攻城狮的第二门课(第1季)第8章 Fragment基础概述
- 区块链2.0(二):区块链在金融服务领域的运用案例
- C和C++中struct和typedef struct的分析
- 接口的应用——工厂设计模式
- [NOIP2017模拟]Bovine Genomics
- 区块链2.0(三):智能合约应用案列及相关法律问题
- 近 100 个 Linux 常用命令大全
- 学习-Thrift
- Test 8 for NOIP- Result for Day2
- 函数可重入性(Reentrancy)
- 哇!这就是Makefile?
- CCF 201703-4 地铁修建(最小生成树 + 并查集)
- Linux帮助命令