比赛链接
有疑问欢迎评论区指正
E2. Three Blocks Palindrome (hard version)
思路:由于权值最大是200,所以我们可以枚举每种权值作为x的时候的情况。
每种情况都枚举中间的y值即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
int t,n,a[N];
int cnt[201][N];
vector<int>v[201];
int main() {
  	ios::sync_with_stdio(false);
  	for(cin>>t;t;t--){
  		cin>>n;int ans=0;
  		for(int i=1;i<=200;i++)v[i].clear();
  		for(int i=1;i<=n;i++){
  			cin>>a[i];
  			for(int j=1;j<=200;j++)cnt[j][i]=cnt[j][i-1];
  			cnt[a[i]][i]++;
  			ans=max(ans,cnt[a[i]][i]);
  			v[a[i]].pb(i);
  		}
  		for(int i=1;i<=200;i++){
  			int sz=v[i].size();
  			for(int j=1;j*2<=sz;j++){
  				int l=v[i][j-1]+1,r=v[i][sz-j]-1;
  				for(int k=1;k<=200;k++){
  					ans=max(ans,j*2+cnt[k][r]-cnt[k][l-1]);
  				}
  			}
  		}
  		cout<<ans<<'\n';
  	}
 	return 0;
}

F. Robots on a Grid
思路:显然可以把一组点的移动路径归结为一个有向环和一些连在环上的链,其中链上的点全都指向环。
显然,我们在这组点中,能放的机器人最大点数就是环的长度。
那么我们先拓扑排序找到所有不在环上的点,那么剩下的度数不为0的点必然都是环上的点。我们从任意一个环上的点S开始bfs,计算出这组点中的每一个点到S的距离dis。由于两个机器人不能出现在一个点上,那么我们选的点的dis必然是%环周长意义下互不相同,否则必然会有冲突产生。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
int t,n,m,vis[N];
string a[N],b[N];
int fx[4][2]={
	{1,0},{0,1},{-1,0},{0,-1}
};
vector<pair<int,int>>Q;
int main() {
  	ios::sync_with_stdio(false);
  	for(cin>>t;t;t--){
  		cin>>n>>m;int L=0,R=0;
  		vector<vector<int>>d(n,vector<int>(m,0));
  		for(int i=0;i<n*m;i++)vis[i]=0;
  		for(int i=0;i<n;i++)cin>>b[i];
  		for(int i=0;i<n;i++)cin>>a[i];
  		for(int i=0;i<n;i++){
  			for(int j=0;j<m;j++){
  				if(a[i][j]=='U')d[i-1][j]++;
  				if(a[i][j]=='D')d[i+1][j]++;
  				if(a[i][j]=='L')d[i][j-1]++;
  				if(a[i][j]=='R')d[i][j+1]++;
  			}
  		}
  		Q.clear();
  		//度数最终不为0的点必然在环上
  		for(int i=0;i<n;i++){
  			for(int j=0;j<m;j++){
  				if(!d[i][j])Q.pb(mp(i,j));
  			}
  		}
  		for(int i=0;i<Q.size();i++){
  			auto now=Q[i];
  			int dx=now.fi,dy=now.se;
  			if(a[dx][dy]=='U')dx--;
  			else if(a[dx][dy]=='D')dx++;
  			else if(a[dx][dy]=='L')dy--;
  			else if(a[dx][dy]=='R')dy++;
  			if(--d[dx][dy]==0)Q.pb(mp(dx,dy));
  		}
  		vector<vector<int>>dis(n,vector<int>(m,0));
  		for(int i=0;i<n;i++){
  			for(int j=0;j<m;j++)if(!vis[i*m+j]&&d[i][j]!=0){
  				Q.clear();
  				Q.pb(mp(i,j));	
  				dis[i][j]=0;
  				int tmpL=0,tmpR=0;
  				for(int sz=0;sz<Q.size();sz++){
  					auto f=Q[sz];
  					vis[f.fi*m+f.se]=1;//标记被访问过
  					tmpL+=(d[f.fi][f.se]!=0);//计算环
  					for(int k=0;k<4;k++){
  						int dx=f.fi+fx[k][0];
  						int dy=f.se+fx[k][1];
  						if(dx<0||dy<0||dx>=n||dy>=m||vis[dx*m+dy])continue;
  						if(a[dx][dy]=='U')dx--;
  						else if(a[dx][dy]=='D')dx++;
  						else if(a[dx][dy]=='L')dy--;
  						else if(a[dx][dy]=='R')dy++;
  						if(dx==f.fi&&dy==f.se){
  							Q.pb(mp(f.fi+fx[k][0],f.se+fx[k][1]));
  							dis[f.fi+fx[k][0]][f.se+fx[k][1]]=dis[f.fi][f.se]+1;
  						}
  					}
  				}
  				vector<int>cy(tmpL,0);
  				for(auto k:Q)if(b[k.fi][k.se]=='0'){
  					if(!cy[dis[k.fi][k.se]%tmpL])tmpR++;
  					cy[dis[k.fi][k.se]%tmpL]=1;
  				}
  				L+=tmpL;R+=tmpR;
  			}
  		}
  		cout<<L<<' '<<R<<'\n';
  	}
 	return 0;
}