「CF666X」 Codeforces Round #349 (Div. 1)
A. Reberland Linguistics
此题最重要的是理解题意!!!
英语渣伤不起
给定一个字符串,先去掉一个长度至少为5的前缀,要求把剩下的字符串划分成长度为2或3的串,这些串相邻之间不能完全相同,问可能有哪些长度为2或3的串
看错题意就写了个哈希+搜索一直wa,后来领悟了就没另起炉灶,改成了牵强的记搜
大概和dp差不多意思,f[i][0/1]表示前i个字符,最后一个串长度为2/3是否可行,转移显然。。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
#include<map> #include<set> #include<cmath> #include<stack> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define pi acos(-1) #define eps 1e-13 #define mod 10000007 #define inf 1000000000 #define ll long long using namespace std; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,top; char c[10005]; int path[10005],ans[20005],v[10005][3],mark[10005][3]; string q[20005]; int get(int x,int y) { if(y>n)return 0; int H=0; for(int i=x;i<=y;i++) H=H*27+c[i]-'a'+1; return H; } int dfs(int x,int K,int Last,int d) { if(x==n+1)return 1; if(x>=n)return 0; if(mark[x][d])return mark[x][d]; mark[x][d]=-1; for(int k=1;k<=2;k++) { int t=v[x][k]; if(Last!=t) { path[K]=t; if(dfs(x+k+1,K+1,t,k)==1) { mark[x][d]=1; ans[t]=1; } } } return mark[x][d]; } int main() { scanf("%s",c+1); n=strlen(c+1); for(int i=1;i<=n-1;i++)v[i][1]=get(i,i+1); for(int i=1;i<=n-2;i++)v[i][2]=get(i,i+2); for(int i=5;i<=n;i++) dfs(i+1,1,-1,0); for(int i=1;i<=n;i++) for(int k=1;k<=2;k++) if(i+k<=n&&ans[v[i][k]]) { string s=""; for(int t=0;t<=k;t++) s+=c[i+t]; ans[v[i][k]]=0; q[++top]=s; } sort(q+1,q+top+1); cout<<top<<endl; for(int i=1;i<=top;i++) cout<<q[i]<<endl; return 0; } |
B. World Tour
给定一张边权为1的有向图,求四个不同点A, B, C, D
使得dis(A, B) + dis(B, C) + dis(C, D)取最大值
先bfs出任意两点的距离,f(i, 0-2)表示从i出发的最远的三个点,g(i, 0-2)表示到i的最远的三个点
枚举B和C,再枚举3 * 3个点对,选出最优的A和D
保留三个点的原因是保证A, B, C, D互不相同
复杂度n^2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
#include<map> #include<set> #include<cmath> #include<stack> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define pa pair<int,int> #define pi acos(-1) #define eps 1e-13 #define mod 10000007 #define inf 1000000000 #define ll long long using namespace std; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,ans,ans1,ans2,ans3,ans4; vector<int>e[5005]; queue<int>q; int d[3005][3005]; int f[3005][3],g[3005][3]; void get(int x) { q.push(x); for(int i=1;i<=n;i++)d[x][i]=inf; d[x][x]=0; while(!q.empty()) { int t=q.front();q.pop(); for(int i=0;i<e[t].size();i++) if(d[x][e[t][i]]==inf) { d[x][e[t][i]]=d[x][t]+1; q.push(e[t][i]); } } } void pre(int x) { for(int i=1;i<=n;i++) { int t=i; for(int j=0;j<3;j++) { int p=f[x][j]; if(d[p][x]<d[t][x]&&d[t][x]!=inf)swap(f[x][j],t); } t=i; for(int j=0;j<3;j++) { int p=g[x][j]; if(d[x][p]<d[x][t]&&d[x][t]!=inf)swap(g[x][j],t); } } } void solve(int u,int v) { if(d[u][v]==inf)return; for(int i=0;i<3;i++) for(int j=0;j<3;j++) { int p1=f[u][i],p2=g[v][j]; if(p1==0||p2==0)continue; if(p1!=p2&&p1!=v&&p2!=u&&d[p1][u]+d[u][v]+d[v][p2]>ans) { ans=d[p1][u]+d[u][v]+d[v][p2]; ans1=p1,ans2=u,ans3=v,ans4=p2; } } } int main() { n=read();m=read(); for(int i=1;i<=m;i++) { int u,v; u=read();v=read(); e[u].push_back(v); } for(int i=1;i<=n;i++)get(i); for(int i=1;i<=n;i++)pre(i); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i!=j) solve(i,j); cout<<ans1<<' '<<ans2<<' '<<ans3<<' '<<ans4<<endl; return 0; } |
Subscribe