前言
这是我第
4
4
4 次做出
F
F
F 题,庆祝上蓝!
正题
本题解提供 A − F A-F A−F 题题解,欢迎诸位大佬参考。
第 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;
}
(未完待续……)