您的位置:首页 > 其它

2015 ACM/ICPC 沈阳现场赛

2015-11-01 21:37 441 查看
<题目链接>hdu

B.Bazinga

题意:

For n given
strings S1,S2,⋯,Sn,
labelled from 1 to n,
you should find the largest i (1≤i≤n) such
that there exists an integer j (1≤j<i) and Sj is
not a substring of Si.
A substring of a string Si is
another string that occurs in Si.
For example, ``ruiz" is a substring of ``ruizhang", and ``rzhang" is not a substring of ``ruizhang".

分析:先将前n-1个串在第n个串里面的位置区间找到,然后判断两个串的时候先比较一下位置区间,假如有包含关系,就肯定一个是另一个的子串,如果不是再KMP比较一次。

代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 1E9+9;

char s[502][2002];
int fail[502][2002];
int Len[502];

void getnext(int *Next,char *str,int id)
{
int len=strlen(str);
Len[id]=len;
Next[0]=-1;
int k=-1;
int j=0;
while(j<len)
{
if(k==-1 ||str[j]==str[k])
{
++j;
++k;
if(str[j]!=str[k])
Next[j]=k;
else
Next[j]=Next[k];
}
else
k=Next[k];
}
}

int match(int id_a,int id_b,int *f)
{
char *a=s[id_a],*b=s[id_b];
int len1=Len[id_a],len2=Len[id_b];
int i=0,j=0,d=len1-len2;
while(i<len1 && d>=i-j)
{
if(j==-1 || a[i]==b[j])
{
++i;
++j;
if(j>=len2)
return i-len2;
}
else
j=f[j];
}
return -1;
}

pair <int ,int > p[20000];

int main()
{
// freopen("da.txt","r",stdin);
// freopen("da1.txt","w",stdout);
int ncase,i,j,n;
scanf("%d",&ncase);
for(int T=1;T<=ncase;T++)
{
scanf("%d%*c",&n);
for(i=1;i<=n;i++)
{
gets(s[i]);
getnext(fail[i],s[i],i);
}
int fg=-1;
for(i=1;i<n;i++)
{
int pos=match(n,i,fail[i]);
if(pos==-1)
{
fg=1;
break;
}
p[i]=make_pair(pos,pos+Len[i]-1);
}
if(fg!=-1)
{
printf("Case #%d: %d\n",T,n);
continue ;
}
// for(i=1;i<n;i++)
// {
// printf("[%d %d]\n",p[i].first,p[i].second);
// }
for(i=n-1;i>1 && fg==-1;i--)
{
for(j=1;j<i;j++)
{
if(!(p[i].first<=p[j].first && p[i].second>=p[j].second) && match(i,j,fail[j])==-1)
{
fg=i;
break;
}
}
}
printf("Case #%d: %d\n",T,fg);
}
return 0;
}


M.Meeting

题意:给你一个图G,G右很多块组成,每一块里面有Si个点,这Si个点的关系是从一个点到另一个点的时间为t。现在问两个人分别从点1和点n同时出发,最快需要多长的时间。

分析:图其实是可以存下的。。。



转化--->



这样,求出从1到每个点的最短路,再求出n到每个点的最短路,枚举位置即可。

代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
const LL INF = 1E18+9;
const int maxn = 1e6;

struct node
{
int id;
int w;
int next;
}List[maxn<<3];
int head[maxn],cnt;
LL cost1[maxn],cost2[maxn],cost[maxn];
bool visit[maxn];
void Init()
{
cnt=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w) // u-->v
{
List[cnt].id=v;
List[cnt].w=w;
List[cnt].next=head[u];
head[u]=cnt++;
}
queue <int > q;
void slack(int u,int v,LL w)
{
if(cost[u]+w<cost[v])
{
cost[v]=cost[u]+w;
if(!visit[v])
{
q.push(v);
visit[v]=true;
}
}
}
void spfa()
{
while(!q.empty())
{
int temp=q.front();
q.pop();
visit[temp]=false;
int hash=head[temp];
while(hash!=-1)
{
slack(temp,List[hash].id,List[hash].w);
hash=List[hash].next;
}
}
}
int ans[maxn];

int main()
{
int nCase,n,m,i,j,t,num,u;
scanf("%d",&nCase);
for(int T=1;T<=nCase;T++)
{
scanf("%d%d",&n,&m);
int cur=1e5+6;
Init();
for(i=1;i<=m;i++)
{
scanf("%d%d",&t,&num);
while(num--)
{
scanf("%d",&u);
add(u,cur,t);
add(cur,u,0);
}
cur++;
}
fill(cost1,cost1+maxn,INF);
fill(cost2,cost2+maxn,INF);
fill(cost,cost+maxn,INF);
cost[1]=0;
q.push(1);
spfa();
swap(cost,cost1);
cost
=0;
q.push(n);
spfa();
swap(cost,cost2);
LL Min=INF+1,tmp;
for(i=1;i<=n;i++)
{
tmp=max(cost1[i],cost2[i]);
if(tmp<Min)
Min=tmp;
}
printf("Case #%d: ",T);
if(Min>=INF)
{
puts("Evil John");
continue ;
}
printf("%lld\n",Min);
int p=0;
for(i=1;i<=n;i++)
{
tmp=max(cost1[i],cost2[i]);
if(tmp==Min)
ans[p++]=i;
}
printf("%d",ans[0]);
for(i=1;i<p;i++)
{
printf(" %d",ans[i]);
}
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACMICPC