2024-11-30 10:15阅读: 7评论: 0推荐: 0

Atcoder Beginner Contest 330 题解

前言

过于水的一场。

A Counting Passes

题面

给出一个长度为 n 的序列 a,求出 a 之中大于等于 l 的数个个数。

1n100,1ai1000,1l1000

制約

  • 入力は全て整数
  • 1  N  100
  • 1  L  1000
  • 0  Ai  1000

思路

简单暴力。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,l,cnt;
int a[1001];
signed main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>l;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		if(a[i]>=l) cnt++;
	}
	cout<<cnt<<"\n";
	return 0;
}

B Minimize Abs 1

题面

有一个长为 N 的数列 A 和两个整数 L,R。对于每个 Ai,你需要选出一个数 Xi,满足如下条件:

  • LXiR
  • 对于所有整数 LYR|XiAi||YAi|

制約

  • 1 N 2× 105
  • 1 L R  109
  • 1 Ai 109
  • 入力は全て整数

思路

只需要根据范围求出 |YAi| 的最小值,找一个 Xi 使得 |XiAi|=min|YAi| 即可。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[200005],l,r;
signed main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>l>>r;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(int i=1;i<=n;i++)
	{
		if(l<=a[i]&&a[i]<=r) cout<<a[i]<<" ";
		else if(a[i]<l)
		{
			cout<<l<<" ";
		}
		else{
			cout<<r<<" ";
		}
	}
	return 0;
}

C Minimize Abs 2

题面

给你一个整数 D ,找到对于非负整数 x,y|x2+y2D| 的最小值

制約

  • 1 D  2× 1012
  • 入力は全て整数

思路

只需枚举 xy[Dx2,Dx2+1],再计算最小值即可。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int d;
int minn=2e9;
signed main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>d;
	for(int i=1;i<=1e6;i++)
	{
		int x=i;
		int y=sqrt(abs(x*x-d));
		int y2=y+1;
		minn=min(minn,abs(x*x+y*y-d));
		minn=min(minn,abs(x*x+y2*y2-d));
	}
	cout<<minn<<"\n";
	return 0;
}

D Counting Ls

Tag:排列组合

题面

现有一个 NN 列的字符数组,满足对于每个 1iN1jN 都有 Si,jo,x

请问在该数组里有多少个满足以下条件的三方格组:

  • 三个格子内都是 o

  • 三个方格互不相同

  • 恰好有两个方格在同一行

  • 恰好有两个方格在同一列

思路

先预处理每一行 o 的数量 hi 和每一列 o 的数量 li

对于每一个位置,如果它是 o,那它的贡献就是 (hi1)×(li1)

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,ans;
char a[2001][2001];
int h[2001],l[2001];
int hz,lz;
signed main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cin>>a[i][j];
			if(a[i][j]=='o') h[i]++;
		}
		hz+=h[i];
	}
	for(int j=1;j<=n;j++)
	{
		for(int i=1;i<=n;i++)
		{
			if(a[i][j]=='o') l[j]++;
		}
		lz+=l[j];
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(a[i][j]=='o') ans+=(h[i]-1)*(l[j]-1);
		}
	}
	cout<<ans<<"\n";
	return 0;
}

E Mex and Update

Tag: STL

题面

给定一个序列,支持单点修改,每次修改后输出全局 mex

一个序列的 mex 定义为,序列中最小的没有出现过的非负整数。

制約

  • 入力は全て整数
  • 1  N,Q  2 × 105
  • 0  Ai  109
  • 1  ik  N
  • 0  xk  109

思路

首先易证明一个长度为 n 的序列的 mex 最大为 n

那我们可以用一个 set 存没出现过的数,一个 map 记录每个数字在序列里出现的次数。

对于每次修改,我们将 mpax1,将 mpy1

如果 mpax 减到 0,把这个数字加到 set。

如果 mpy1,则从 set 里删除这个数。

最后输出 set 的第一个数字就行了。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,q;
int a[200005];
set<int> s;
map<int,int> mp;
signed main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>q;
	for(int i=0;i<=n+1;i++) s.insert(i);
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
		if(a[i]>n) a[i]=n+1;
		if(s.count(a[i]))s.erase(a[i]);
		mp[a[i]]++;
	}
	while(q--)
	{
		int x,y;
		cin>>x>>y;
		if(y>n) y=n+1;
		mp[a[x]]--;
		mp[y]++;
		if(mp[y]==1) s.erase(y);
		if(mp[a[x]]==0) s.insert(a[x]);
		cout<<*s.begin()<<"\n";
		a[x]=y;
		
	}
	return 0;
}

F Minimize Bounding Square

Tag:二分

题面

给定平面内 n 个点,你可以把这 n 个点一共在坐标上移动 k 次。移动可以是横着或者竖着走 1 单位长度。移动结束后会有一个最小的正方形把所有点都框起来。最小化这个正方形的边长。

制約

  • 入力は全て整数
  • 1  N  2 × 105
  • 0  K  4 × 1014
  • 0  Xi,Yi  109

思路

二分答案,对于一个边长 x,只要使得每一对的 xiyi 经过 k 次操作后绝对值在 x 以内即可。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,k;
int x[200005],y[200005];
bool check(int len){
	int cnt=0;
	for(int i=1;i<=(n>>1);i++)cnt+=max(0LL,x[n-i+1]-x[i]-len)+max(0LL,y[n-i+1]-y[i]-len);
	return cnt<=k;
}
signed main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>k;
	for(int i=1;i<=n;i++)
	{
		cin>>x[i]>>y[i];
	}
	sort(x+1,x+n+1);
	sort(y+1,y+n+1);
	int l=0,r=1e16,ans=0;
	while(l<=r)
	{
		int mid=(l+r)>>1;
		if(check(mid))
		{
			ans=mid;
			r=mid-1;
		}
		else l=mid+1;
	}
	cout<<ans<<"\n";
	return 0;
}

本文作者:yaaaaaan

本文链接:https://www.cnblogs.com/yaaaaaan/p/18578127

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   yaaaaaan  阅读(7)  评论(0编辑  收藏  举报
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
🔑
点击右上角即可分享
微信分享提示