链接:戳这里
A + B 就不写了吧
First-rate specialists graduate from Berland State Institute of Peace and Friendship. You are one of the most talented students in this university. The education is not easy because you need to have fundamental knowledge in different areas, which sometimes are not related to each other.
For example, you should know linguistics very well. You learn a structure of Reberland language as foreign language. In this language words are constructed according to the following rules. First you need to choose the "root" of the word — some string which has more than 4 letters. Then several strings with the length 2 or 3 symbols are appended to this word. The only restriction — it is not allowed to append the same string twice in a row. All these strings are considered to be suffixes of the word (this time we use word "suffix" to describe a morpheme but not the few last characters of the string as you may used to).
Here is one exercise that you have found in your task list. You are given the word s. Find all distinct strings with the length 2 or 3, which can be suffixes of this word according to the word constructing rules in Reberland language.
Two strings are considered distinct if they have different length or there is a position in which corresponding characters do not match.
Let's look at the example: the word abacabaca is given. This word can be obtained in the following ways: , where the root of the word is overlined, and suffixes are marked by "corners". Thus, the set of possible suffixes for this word is {aca, ba, ca}.
The only line contains a string s (5 ≤ |s| ≤ 104) consisting of lowercase English letters.
On the first line print integer k — a number of distinct possible suffixes. On the next k lines print suffixes.
Print suffixes in lexicographical (alphabetical) order.
abacabaca
3 aca ba ca
abaca
0
The first test was analysed in the problem statement.
In the second example the length of the string equals 5. The length of the root equals 5, so no string can be used as a suffix.
题意:
这里连续的切长度为(2|3)的后缀字串还有一个要求,就是相邻的两个字串假如长度都为2,则这两个字串不能相等
同理长度为3也一样
要求输出能切的字串的个数,并把所有的字串字典序输出
比赛的时候我看错了一点条件,只是连续的两个长度相等的字串不能一样,而不是出现过就不能一样了(mdzz)
思路:
既然必须从后往前连续的分别去切长度为(2|3)的字串,那么我们把字符串翻转一下,设置dp状态
dp[i][0]表示第i个位置取前两个并且可取 dp[i][0]=1
如何判断可取 即 dp[i-2][1]=1 || (dp[i-2][0] && (s[i]!=s[i-2] || s[i-1]!=s[i-3]))
dp[i-2][1]=1表示第i-2的位置取了前三个
dp[i-2][0] && (s[i]!=s[i-2] || s[i-1]!=s[i-3]) 表示第i-2个位置取了前两个
并且当前的字串(s[i]s[i-1])!=(s[i-2]s[i-3])
dp[i][1]表示第i个位置取前三个并且可取 dp[i][1]=1
显然和上面的状态差不多
具体看代码
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<iomanip>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
using namespace std;
int F[10100][2];
vector<string > V;
char s[10010];
int main(){
cin>>s;
int n=strlen(s);
if(n<=5) {
printf("0\n");
return 0;
}
reverse(s,s+n);
if(n-5>=2){string p="";p+=s[1];p+=s[0];V.push_back(p);}
if(n-5>=3){string p="";p+=s[2];p+=s[1];p+=s[0];V.push_back(p);}
F[1][0]=F[2][1]=1;
for(int i=3;i<n-5;i++){
if( F[i-2][1] || (F[i-2][0] && (s[i]!=s[i-2] || s[i-1]!=s[i-3])) ){
string p="";p+=s[i];p+=s[i-1];V.push_back(p);
F[i][0]=1;
}
if(i>=4){
if( F[i-3][0] || (i-5>=0 && F[i-3][1] && (s[i]!=s[i-3] || s[i-1]!=s[i-4] || s[i-2]!=s[i-5])) ){
string p="";p+=s[i];p+=s[i-1];p+=s[i-2];V.push_back(p);
F[i][1]=1;
}
}
}
sort(V.begin(),V.end());
V.erase(unique(V.begin(),V.end()),V.end());
cout<<V.size()<<endl;
for(int i=0;i<V.size();i++)
cout<<V[i]<<endl;
return 0;
}
给出n个点m条边的有向图, 每条边的长度为1
要求找出四个点a,b,c,d使得 a->b + b->c + c->d 的距离最大 其中a->b ,b->c ,c->d代表两点之间的最短路径
(1<=n<=3000) (1<=m<=5000)
思路:
1:先用复杂度内的最短路算法求出所有的i->j的最短路
2:我们可以先枚举所有的b->c 然后再去枚举a和d。显然对答案的贡献我们要求最大,所以a->b 和 c->的要尽可能的大
所以我们可以直接求出最大的a->b 和 c->d 但是因为a,b,c,d不能重点 ,我们直接枚举前三大的就可以了
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<iomanip>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF 1e8
using namespace std;
int n,m,tot;
struct edge{
int v,w,next;
}e[5050];
int head[3010],vis[3010];
int mp[3030][3030],dis[3030];
vector< pair<int ,int> > V1[5050];
vector< pair<int ,int> > V2[5050];
void init(){
mst(head,-1);
tot=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j) mp[i][j]=0;
else mp[i][j]=INF;
}
}
}
void Add(int u,int v){
e[tot].v=v;
e[tot].w=1;
e[tot].next=head[u];
head[u]=tot++;
}
void SPFA(int x){
mst(vis,0);
for(int i=1;i<=n;i++) dis[i]=INF;
dis[x]=0;
vis[x]=1;
queue<int> qu;
qu.push(x);
while(!qu.empty()){
int u=qu.front();
qu.pop();
vis[u]=0;
for(int i=head[u];i!=-1;i=e[i].next){
int v=e[i].v;
if(dis[v]>dis[u]+e[i].w){
dis[v]=dis[u]+e[i].w;
if(!vis[v]){
vis[v]=1;
qu.push(v);
}
}
}
}
for(int i=1;i<=n;i++)
mp[x][i]=min(mp[x][i],dis[i]);
}
void solve(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j) continue;
if(mp[i][j]!=INF) V1[i].push_back(make_pair(mp[i][j],j));
if(mp[j][i]!=INF) V2[i].push_back(make_pair(mp[j][i],j));
}
}
for(int i=1;i<=n;i++){
sort(V1[i].begin(),V1[i].end());
reverse(V1[i].begin(),V1[i].end());
sort(V2[i].begin(),V2[i].end());
reverse(V2[i].begin(),V2[i].end());
}
int t1,t2,t3,t4,ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j || mp[i][j]==INF) continue;
for(int k=0;k<3 && k<V1[j].size();k++){
if(i==V1[j][k].second) continue;
if(j==V1[j][k].second) continue;
for(int l=0;l<3 && l<V2[i].size();l++){
if(i==V2[i][l].second) continue;
if(j==V2[i][l].second) continue;
if(V1[j][k].second==V2[i][l].second) continue;
int tmp=V2[i][l].first + mp[i][j] + V1[j][k].first;
if(tmp > ans){
ans=tmp;
t1=V2[i][l].second;
t2=i;
t3=j;
t4=V1[j][k].second;
}
}
}
}
}
cout<<t1<<" "<<t2<<" "<<t3<<" "<<t4<<endl;
///cout<<ans<<endl;
}
int main(){
scanf("%d%d",&n,&m);
init();
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
Add(u,v);
}
for(int i=1;i<=n;i++) SPFA(i);
/*for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
printf("%d ",mp[i][j]);
}
cout<<endl;
}*/
solve();
return 0;
}