C. Cow and Message
题意:
给你一个字符串s,其中间隔为等差数列的子串最多有多少?
思路:
DP
显然该子串只有可能是长度为1或者2的时候子串的数量能尽可能的多。
因为能够成长度为的2以上的子串一定可以先构成长度为2的子串,显然还多了很多限制。
故本题只要计算统计长度为1和2的子串的最大的数量即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 +7;
const ll MAXN = 1e6 + 5;

ll dp[30][30],a[30];
ll res;

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	string s;
	cin>>s;
	for(int i=0;i<s.size();i++){
		int t=s[i]-'a';
		for(int j=0;j<26;j++){
			dp[t][j]+=a[j];//长度为2的
			res=max(res,dp[t][j]);
		}
		a[t]++;//长度为1的子串数量
		res=max(res,a[t]);//取长度为1的子串的max
	}
	cout<<res<<endl;
	return 0;
}

D. Cow and Fields
题意:
在所给k个点之间连一条边,求出最大的最短路是多少并输出。

思路:
假设连边的点为x,y;
那么最大的最短路为min(1到x的距离+1+y到n的距离,1到y的距离+1+x到n的距离)
设1到x的距离为ax y到n的距离设为ny 同理…略
即求min(ax+1+ny,ay+1+nx)
当ax+ny<ay+nx的时候取前者,移项可得ax-nx<=ay-ny的时候取前者。
要取的最大的最短路,则应当使ai-ni尽可能的大,可利用sort排序完成。
BFS两次:第一次求出1到任意一点的距离,第二次求出n到任意一点的距离。
排序 遍历求最大值

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 +7;
const ll MAXN = 2e5 + 5;

vector<int>G[MAXN];

int a[MAXN];
int dis1[MAXN],disn[MAXN];
queue<int>q;
bool vis[MAXN];

void bfs(int st,int dis[]){
	q.push(st);
	memset(vis,0,sizeof(vis));
	dis[st]=0;
	vis[st]=1;
	while(!q.empty()){
		int top=q.front();
		q.pop();
		for(auto v:G[top]){
			if(!vis[v]){
				dis[v]=dis[top]+1;
				q.push(v);
				vis[v]=1;
			}
		}
	}
}

vector<pair<int,int> >V;

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	int n,m,k;
	cin>>n>>m>>k;
	for(int i=1;i<=k;i++){
		cin>>a[i];
	}
	while(m--){
		int x,y;
		cin>>x>>y;
		G[x].push_back(y);
		G[y].push_back(x);
	}
	bfs(1,dis1);
	bfs(n,disn);
	int res=0;
	for(int i=1;i<=k;i++){
		V.push_back({dis1[a[i]]-disn[a[i]],a[i]});
	}
	sort(V.begin(),V.end());
	int ans=0;
	int tmp=0;
	for(int i=0;i<V.size();i++){
		if(i!=0){
			ans=max(ans,tmp+disn[V[i].second]+1);
		}
		tmp=max(tmp,dis1[V[i].second]);
	}
	cout<<min(ans,dis1[n]);
	return 0;
}