HDU-5510 Bazinga、HDU-5521 Meeting
来源:互联网 发布:淘宝差评拦截在哪设置 编辑:程序博客网 时间:2024/06/05 18:22
Bazinga
题意:给你n个字符串,问你一个最大的i,使得前i-1个字符串至少有一个不是这个串的子串,如果不存在,输出-1。队友用kmp+链表优化过的,虽然不懂他的思路,不过模拟赛的时候A了也没多想。
当时我的思路是:对所有的字符串按长度排序,这样可以优化长度乱序的情况,然后比较相邻两个,如果前一个不是后一个的子串就把前一个串存起来,更新答案,每次比较先与前一个比较,符合的话再和存起来的串比较,不符合把前一个存起来,更新答案。
代码一:只存一个 WA。
const int N=2e6+10;void kmp_pre(char x[],int m,int next[]){ int i,j; j=next[0]=-1; i=0; while(i<m) { while(-1!=j&&x[i]!=x[j]) j=next[j]; next[++i]=++j; }}int nex[2010];bool judge(char x[],char y[]){ int i=0,j=0; int m=strlen(x); int n=strlen(y); kmp_pre(x,m,nex); while(i<n) { while(-1!=j&&y[i]!=x[j]) j=nex[j]; i++,j++; if(j>=m) return true; } return false;}char s[501][2010];int main(){ int t,n; scanf("%d",&t); int t1=t; while(t--) { scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%s",s[i]); int tmp=-1,ans=-1; for(int i=2; i<=n; i++) { if(!judge(s[i-1],s[i])) { ans=i; tmp=i-1; } else { if(tmp!=-1&&!judge(s[tmp],s[i])) ans=i; }// printf("i=%d ans=%d\n",i,ans); } printf("Case #%d: %d\n",t1-t,ans); } return 0;}
代码二:把所有不符合的存起来,暴力判 746ms AC:
const int N=2e6+10;void kmp_pre(char x[],int m,int next[]){ int i,j; j=next[0]=-1; i=0; while(i<m) { while(-1!=j&&x[i]!=x[j]) j=next[j]; next[++i]=++j; }}int nex[2010];bool judge(char x[],char y[]){ int i=0,j=0; int m=strlen(x); int n=strlen(y); kmp_pre(x,m,nex); while(i<n) { while(-1!=j&&y[i]!=x[j]) j=nex[j]; i++,j++; if(j>=m) return true; } return false;}char s[501][2010];int tmp[501];int main(){ int t,n; scanf("%d",&t); int t1=t; while(t--) { scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%s",s[i]); int num=0,ans=-1; for(int i=2; i<=n; i++) { if(!judge(s[i-1],s[i])) { ans=i; tmp[num++]=i-1; } else { for(int j=0; j<num; j++) if(!judge(s[tmp[j]],s[i])) { ans=i; break; } } } printf("Case #%d: %d\n",t1-t,ans); } return 0;}strstr函数却更优,546ms AC:
strstr原理:字符串匹配two way算法 复杂度O(1)啊。
char s[501][2010];int tmp[501];int main(){ int t,n; scanf("%d",&t); int t1=t; while(t--) { scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%s",s[i]); int num=0,ans=-1; for(int i=2; i<=n; i++) {// if(!judge(s[i-1],s[i])) if(strstr(s[i],s[i-1])==NULL) { ans=i; tmp[num++]=i-1; } else { for(int j=0; j<num; j++)// if(!judge(s[tmp[j]],s[i])) if(strstr(s[i],s[tmp[j]])==NULL) { ans=i; break; } } } printf("Case #%d: %d\n",t1-t,ans); } return 0;}
Meeting
近阶段做过最有意思的一个题,目前见过所有图论中很有意思的一个题,被网络流的思想缠绕了很久,最后才想明白建图然后一发板子AC。
题意:两个人分别在1号点和n号点,有m个集合,每个集合里有Si个点,任意两个点之间需要Ti的时间到达。给你n,然后m个集合的信息,求两个人同时出发到一个点的最短时间,如果最短时间有多种方案,从小到大输出这些可行点。思路:由数据范围可以推测任意两个之间建边是行不通的,于是我们可以把每个集合虚拟一个点,虚拟点到这个集合的每个点的长度为Ti,点到虚拟点的长度为0。从1出发跑一遍最短路,从n出发跑一遍最短路,每个点上所需的时间就是1号点到这个点的时间与n号点到这个点时间的最大值。
建边的思想很强,当时想着用网络流跑费用流,但这个可行点却不知道怎么求,但将网络流的建图思想用到最短路上,getAC。
const int N=2e6+10;struct Edge{ int to,next; ll w;} e[N*2];int n,m,tot,cnt,head[N],vis[N];ll d1[N],d2[N];struct node{ int v; ll c; friend bool operator <(node a,node b) { return a.c>b.c; }};priority_queue<node>q;void init(){ for(int i=1; i<=cnt; i++) d1[i]=d2[i]=INF; d1[1]=0,d2[n]=0;}void add(int u,int v,ll w){ e[tot].to=v,e[tot].w=w; e[tot].next=head[u]; head[u]=tot++;}void dij(int s,int f){ while(!q.empty()) q.pop(); memset(vis,0,sizeof(vis)); if(f==1) q.push(node {s,d1[s]}); else q.push(node {s,d2[s]}); while(!q.empty()) { node tmp=q.top(); q.pop(); int x=tmp.v; if(vis[x]) continue; vis[x]=1; for(int i=head[x]; i+1; i=e[i].next) { int v=e[i].to; ll w=e[i].w; if(f==1) { if(d1[v]>d1[x]+w) { d1[v]=d1[x]+w; q.push(node {v,d1[v]}); } } else { if(d2[v]>d2[x]+w) { d2[v]=d2[x]+w; q.push(node {v,d2[v]}); } } } }}int SA[N];int main(){ int t; scanf("%d",&t); int t1=t; while(t--) { scanf("%d%d",&n,&m); tot=0,cnt=n; memset(head,-1,sizeof(head)); int ti,num,x; for(int i=1; i<=m; i++) { scanf("%d%d",&ti,&num); ++cnt; for(int j=0; j<num; j++) { scanf("%d",&x); add(cnt,x,ti); add(x,cnt,0); } } init(); dij(1,1); dij(n,2); ll ans=INF; int AAA=0; for(int i=1; i<=n; i++)ans=min(ans,max(d1[i],d2[i])); for(int i=1; i<=n; i++) { ll TT=max(d1[i],d2[i]); if(TT==ans) SA[AAA++]=i; } printf("Case #%d: ",t1-t); sort(SA,SA+AAA); if(ans==INF) puts("Evil John"); else { printf("%lld\n",ans); for(int i=0; i<AAA; i++) printf("%d%c",SA[i],i==AAA-1?'\n':' '); } } return 0;}
阅读全文
0 0
- HDU-5510 Bazinga、HDU-5521 Meeting
- HDU 5510 Bazinga
- HDU 5510 Bazinga(思维)
- hdu 5510 -Bazinga(kmp)
- hdu 5510 Bazinga(kmp)
- HDU 5510 Bazinga 【strstr】
- HDU-5510 Bazinga
- HDU 5510 Bazinga 【kmp】
- HDU 5510 Bazinga(KMP)
- HDU 5510 Bazinga(kmp)
- Bazinga HDU
- hdu 5510 Bazinga(高效)
- HDU-5510 Bazinga(枚举+剪枝)
- HDU 5510 Bazinga (KMP)
- HDU 5510 Bazinga(KMP)
- HDU-5510 Bazinga(KMP)
- HDU 5510 Bazinga (KMP)
- hdu 5510 Bazinga(KMP+剪枝)
- java基础(1)--反射
- SQL进阶---第一单元(第七到第十课)、Manipulation
- 一些比较实用的网站
- mysqli扩展 增删改
- How to create more time?
- HDU-5510 Bazinga、HDU-5521 Meeting
- 47. Permutations II
- thinkphp5 隐藏index.php方法
- Mybatis操作数据库实现单表/多表查询流程
- java猜数字游戏
- Codeforces 868C Qualification Rounds
- [BZOJ]4300 绝世好题 Dp
- 上机练习2 类与对象
- 类与对象第一题