(Training 5)AtCoder Beginner Contest 188

从没打过atcoder于是vp了一场
atcoder题面比较简洁 难度比cf div2低很多

A - Three-Point Shot

题意:判断是否一个数比另一个数大3以上

#include<iostream>
#include<cstring>
#include<algorithm> 
using namespace std;
const int N=1e5+10;
int main(){
	int x,y;
	cin>>x>>y;
	if(max(x-y,y-x)<=2)cout<<"Yes";
	else cout<<"No";
	return 0;
}

B - Orthogonality

题意:给出2向量问相乘是否为0

#include<iostream>
#include<cstring>
#include<algorithm> 
using namespace std;
const int N=1e5+10;
int a[N],b[N];
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
	scanf("%d",&b[i]);
	int ans=0;
	for(int i=1;i<=n;i++){
		ans+=a[i]*b[i];
	}
	if(ans)puts("No");
	else puts("Yes");
	return 0;
}

C - ABC Tournament

题意:问左边最大的数 和右边最大的数 哪个小 输出位置

#include<iostream>
#include<cstring>
#include<algorithm> 
using namespace std;
const int N=1e5+10;
int a[N],b[N];
int main(){
	int n;
	cin>>n;
	n=(1<<n);
	int maxl=0,l,r,maxr=0;
	for(int i=1;i<=n/2;i++){
		int x;
		scanf("%d",&x);
		if(x>maxl){
			l=i,maxl=x;
		}
	}
	for(int i=n/2+1;i<=n;i++){
		int x;
		scanf("%d",&x);
		if(x>maxr){
			r=i,maxr=x;
		}
	}
	if(maxl>maxr)printf("%d\n",r);
	else printf("%d\n",l);
	return 0;
	
}

D - Snuke Prime

题意:一天支付c元 可以享受所有服务 和给出n个服务的起始时间和结束时间和每天的价格 问享受所有服务的情况下 付出的钱最少是多少
思路:我们把每一个服务差分为 l 到 r+1 l的值为v r+1的值为-v 那么利用前缀和可以的得到某个区间内的值(r+1-l)*v刚好就等于l到r所花费的值
就这样我们按照这样差分 并利用右端点进行排序 从前往后计算即可

#include<iostream>
#include<cstring>
#include<algorithm> 
#include<map>
using namespace std;
const int N=2e5+10;
struct Node{
	int x,v;
	bool operator <(const Node &a)const{
		return x<a.x;
	}
}node[N*2];
int cnt=0;
map<int,bool>mp;
int main(){
	int n,c;
	cin>>n>>c;
	for(int i=1;i<=n;i++){
		int l,r,v;
		scanf("%d%d%d",&l,&r,&v);
		node[++cnt]={l,v};
		node[++cnt]={r+1,-v};
	}
	sort(node+1,node+1+cnt);
	long long ans=0,val=0;
	node[++cnt]={node[2*n].x,0};
	for(int i=1;i<=cnt;i++){
		//cout<<node[i].x<<" "<<val<<" "<<node[i].v<<endl;
		val+=node[i].v;
		if(node[i].x!=node[i+1].x&&val>=0){
			if(val>=c)ans+=1ll*(node[i+1].x-node[i].x)*c;
			else ans+=1ll*(node[i+1].x-node[i].x)*val; 
		}
	}
	cout<<ans;
	return 0;
	
}

E - Peddler

题意:n个城镇m条道路 n个城镇的黄金价格给出 问从最大收益为多少 且不能在城镇买了以后又到当前一个城镇卖 必须按照路径顺序进行出售 此为有向图
思路:记忆化搜索跑一边即可 dfs返回的是该点到后续所有点能卖出的最低价格

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=3e5+10,INF=0x3f3f3f3f;
struct Edge{
	int v,next;
}edge[N];
int w[N],head[N],tot,ans=-INF,st[N];
bool ok[N];
void add(int u,int v){
	edge[++tot]={v,head[u]};
	head[u]=tot;
}
int dfs(int u){
	if(st[u])return st[u];//返回自己儿子的最高售价 
	st[u]=w[u];
	int maxv=-INF;
	for(int i=head[u];i;i=edge[i].next){
		int v=edge[i].v;
		maxv=max(dfs(v),maxv);
	}
	ans=max(maxv-w[u],ans);
	st[u]=max(st[u],maxv);
	return st[u];
}
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&w[i]);
	}
	for(int i=1;i<=m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v);
		ok[v]=1;
	}
	for(int i=1;i<=n;i++){
		if(!ok[i])dfs(i);
	}
	cout<<ans;
	return 0;
}

F - +1-1x2

题意:给出x和y 让x变为y的最少操作数是多少 每次操作x只能+1 -1或者2
vp的时候没时间了
思路:记忆化搜索 当x>=y时我们只能进行x-y次操作
在x<y时我们可以+1或者
2
共2种情况 但是如果是这样进行枚举 会爆longlong 于是采用反向搜索
在x<y 有3种情况 y-x y/2 (y)/2 y为奇数(y+1)/2
因为在y<x时我们直接得 x-y 所以主要操作都是在进行y/2直到y<x 故时间复杂度为logn

#include<iostream>
#include<cstring>
#include<algorithm>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N=1e5+10;
unordered_map<LL,LL>mp;
LL n,m;
LL f(LL x){
	if(n>=x)return mp[x]=n-x;
	if(mp[x])return mp[x];
	LL ans=x-n;
	ans=min(ans,f(x/2)+x%2+1);
	if(x%2)ans=min(ans,f(x/2+1)+2);
	return mp[x]=ans;
	
}
int main(){
	cin>>n>>m;
	cout<<f(m);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值