(Atcoder Beginner Contest 348)题解

发布于:2024-04-09 ⋅ 阅读:(582) ⋅ 点赞:(0)

前言

这是我第 4 4 4 次做出 F F F 题,庆祝上蓝!
在这里插入图片描述

正题

本题解提供 A − F A-F AF 题题解,欢迎诸位大佬参考。

第 1 题 Penalty Kick

照例很水,模拟即可。

#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
	int n; cin>>n;
	for (int i=1; i<=n; i++){
		if (i%3==0) cout<<"x";
		else cout<<"o";
	}
	return 0;
} 

第 2 题 Farthest Point

也是很简单,枚举即可。注意为了 不丢失精度,我们用到了显而易见的定理:
如果:
x 2 > y 2 x^2>y^2 x2>y2

那么:
x > y x>y x>y

#include <bits/stdc++.h>
using namespace std;
#define int long long
int x[110],y[110];
signed main(){
	int n; cin>>n;
	for (int i=1; i<=n; i++){
		cin>>x[i]>>y[i];
	}for (int i=1; i<=n; i++){
		int mx=0; int id;
		for (int j=1; j<=n; j++){
			int dis=(x[j]-x[i])*(x[j]-x[i])+(y[j]-y[i])*(y[j]-y[i]);
			if (dis>mx) mx=dis,id=j; 
		}cout<<id<<"\n";
	}
	return 0;
} 

第 3 题 Colorful Beans

需要使用到 m a p map map 容器,不知诸位大佬是否知道。
这里不太方便讲述,就找了一篇:map 使用方法-CSDN

#include <bits/stdc++.h>
using namespace std;
#define int long long
map <int,int> mp;
signed main(){
	int n; cin>>n;
	for (int i=1; i<=n; i++){
		int u,v; cin>>v>>u; 
		if (!mp[u]) mp[u]=v;
		else mp[u]=min(mp[u],v);
	}int mx=0;
	for (auto x:mp) mx=max(mx,x.second);
	cout<<mx;
	return 0;
} 

第 4 题 Medicines on Grid

注意,题中的药物只会让你的能量值 变为 某个值,而 不是增加

那么我们可以注意到,我们把药物也变成图,两个药物 a , b a,b a,b 有边,仅当 a a a 处吃药后可以不使用任何药物走到 b b b。我们可以在 a a a b f s bfs bfs,查看是否可以在药物作用内走到 b b b

有了这个定义,我们可以求解问题了!假设我们的起点处的药物叫 S S S,作用范围 0 0 0,终点处是 T T T,作用范围是 0 0 0,那么我们可以在图上再跑 b f s bfs bfs,查看 S S S 是否可以走到 T T T

#include <bits/stdc++.h>
using namespace std;
#define int long long
int mx[4]={0,0,-1,1};
int my[4]={-1,1,0,0};
bool vis[310][310];
string mp[310];
int id[310][310],n,m,k;
vector <int> vc[310];
int x[310],y[310],e[310],ans[310];
void dfs(int x,int y,int ma){
	queue <int> qx,qy,qz;
	qx.push(x); qy.push(y); qz.push(0);
	while (qx.size()){
		int x=qx.front(); qx.pop();
		int y=qy.front(); qy.pop();
		int z=qz.front(); qz.pop();
		if (z==ma) continue; 
		for (int i=0; i<4; i++){
			int nx=x+mx[i];
			int ny=y+my[i];
			if (nx<1||ny<1||nx>n||ny>m) continue;
			if (vis[nx][ny]||mp[nx][ny]=='#') continue;
			qx.push(nx); qy.push(ny); qz.push(z+1);
			vis[nx][ny]=1;
		} 
	}
}void solve(int x){
	for (auto u:vc[x]){
		if (!ans[u]){
			ans[u]=1; solve(u);
		}
	}
}signed main(){
	cin>>n>>m;
	for (int i=1; i<=n; i++){
		cin>>mp[i]; mp[i]=" "+mp[i];
	}cin>>k; int s,t;
	for (int i=1; i<=k; i++){
		cin>>x[i]>>y[i]>>e[i];
		id[x[i]][y[i]]=i;
	}for (int i=1; i<=n; i++){
		for (int j=1; j<=m; j++){
			if (mp[i][j]=='S') s=id[i][j];
			if (mp[i][j]=='T'){
				if (id[i][j]) t=id[i][j];
				else k++,t=k,id[i][j]=k,x[k]=i,y[k]=j,e[k]=0;
			}
		}
	}for (int i=1; i<=k; i++){
		memset(vis,0,sizeof(vis));
		vis[x[i]][y[i]]=1;
		dfs(x[i],y[i],e[i]);
		for (int j=1; j<=n; j++){
			for (int k=1; k<=m; k++){
				if (vis[j][k]&&id[j][k]){
					vc[i].push_back(id[j][k]);
				}
			}
		}
	}ans[s]=1; solve(s);
	cout<<(ans[t]?"Yes":"No");
	return 0;
} 

第 5 题 Minimize Sum of Distances

这道题看似很难,但这里介绍一种方法:换根 D P DP DP

假设现在有一棵树(如下图),它的根是 u u u,我们要把根换到 v v v,求权值(每个点的深度乘点权和)变化。

在这里插入图片描述

那么可以发现,它增长了黑色权值和减红色权值和。黑色好算,是 v v v 的子树,红色可以用总权值减黑色计算。

#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,m,a[2010][2010];
bitset <2010> s[1010],ans[2010];
vector <int> vc[1010];
signed main(){
	cin>>n>>m;
	for (int i=1; i<=n; i++){
		for (int j=1; j<=m; j++){
			cin>>a[i][j];
		}
	}for (int j=1; j<=m; j++){
		memset(s,0,sizeof(s)); 
		for (int i=1; i<1000; i++) vc[i].clear();
		for (int i=1; i<=n; i++){
			s[a[i][j]][i]=1; vc[a[i][j]].push_back(i);
		}for (int i=1; i<1000; i++){
			for (auto x:vc[i]){
				ans[x]^=s[i];
			}
		}
	}int cnt=0;
	for (int i=1; i<=n; i++){
		for (int j=i+1; j<=n; j++){
			if (ans[i][j]) cnt++;
		}
	}cout<<cnt;
	return 0;
} 

(未完待续……)


网站公告

今日签到

点亮在社区的每一天
去签到