AtCoder Beginner Contest 155 题解

传送门:这里

这场好难,枯了。

A

分类讨论

#include<bits/stdc++.h>
using namespace std;

int main(){
	int a[3];
	for(int i=0; i<3; i++) cin>>a[i];
	sort(a, a+3);
	
	if(a[0]==a[1] && a[1]!=a[2] || a[0]!=a[1] && a[1]==a[2]) puts("Yes");
	else puts("No");
	return 0;
}

B

模拟

#include<bits/stdc++.h>
using namespace std;

int main(){
	int n; cin>>n;
	
	bool ok=true;
	while(n--){
		int t; cin>>t;
		if(t%2==0){
			if(t%3!=0 && t%5!=0) ok=false;
		}
	}
	puts(ok? "APPROVED": "DENIED");
	return 0;
}

C

模拟

#include<bits/stdc++.h>
using namespace std;

map<string, int> mp;

int main(){
	int n; cin>>n;
	while(n--){
		string t; cin>>t;
		mp[t]++;
	}
	
	int num=0;
	for(auto i: mp) num=max(num, i.second);
	
	for(auto i: mp) if(i.second==num) cout<<i.first<<endl;
	return 0;
}

D

二分答案,看看二分出来的 v 在所有数中的排名。麻烦在于求排名的时候也要二分 qwq

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;

#define int long long

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

const int N=2e5+5;

int n, k;
int w[N];

int get_rank(int v){
	int rk=0;
	rep(i,1,n-1){
		int cur=w[i];
		if(cur<0){
			int L=i+1, R=n;
			while(L<R){
				int mid=L+R>>1;
				if(v>cur*w[mid]) R=mid;
				else L=mid+1; 
			}
			if(v>cur*w[L]) rk+=n-L+1;
		}
		else{
			int L=i+1, R=n;
			while(L<R){
				int mid=L+R+1>>1;
				if(v>cur*w[mid]) L=mid;
				else R=mid-1;
			}
			if(v>cur*w[L]) rk+=L-i;
		}
	}
	rk++;
	// debug(rk);
	return rk;
}

signed main(){
	read(n), read(k);
	rep(i,1,n) read(w[i]);
	sort(w+1, w+1+n);
	
	int l=-1e18, r=1e18;
	while(l<r){
		int mid=l+r+1>>1;
		if(get_rank(mid)<=k) l=mid;
		else r=mid-1;
	}
	cout<<l<<endl;
	
    return 0;
}

E

分析

我们采取 dp 的做法。

为了直观地考虑这个问题,我们将原串用 a 表示,根据题意,我们的目标是最小化 (bi+ci) (求最小代价)。

anan1...a1+bnbn1...b1=cncn1...c1

不失一般性,考察第 i 位,分成两种情况讨论:

  • i 位发生进位。

  • i 位不发生进位。

对于第一种情况:
我们有 ai+bi=10+ci (因为发生了进位),要最小化 bi+ci

因为 bi+ci=2bi+ai10 ,我们只需要最小化 bi ,故让 bi=10ai 即可,相应地,可得 ci=0

类似地,在第二种情况中可得相应的 bi=0, ci=ai

下面开始 dp:f[i][0/1] 表示第 i 位不进位 / 进位下前 i 位的最小代价。

如果第 i1 位没有发生进位,那么第 i 位没有受到影响,直接针对上面的讨论进行转移即可。

如果发生进位,那么第 i 位的 ai 相当于 ai+1 类似地进行转移。

结合转移方程理解:

f[i][0]=min(f[i1][0]+a[i], f[i1][1]+a[i]+1)

f[i][1]=min(f[i1][0]+10a[i], f[i1][1]+101a[i]);

代码:

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;

#define rep(i,a,b) for(int i=(a);i<=(b);i++)

int t(char ch){ // char 转 int
	return ch-'0';
}

const int N=1e6+5;

int f[N][2];

int main(){
	string s; cin>>s; int n=s.size(); reverse(s.begin(), s.end()); s=' '+s;
	
	f[0][1]=1, f[0][0]=0;
	rep(i,1,n){
		f[i][0]=min(f[i-1][0]+t(s[i]), f[i-1][1]+t(s[i])+1);
		f[i][1]=min(f[i-1][0]+10-t(s[i]), f[i-1][1]+10-1-t(s[i]));
	}
	cout<<min(f[n][1]+1, f[n][0]);
	
    return 0;
}
posted @   HinanawiTenshi  阅读(39)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示