2023 山东省赛 【9.28训练补题】

Dashboard - The 13th Shandong ICPC Provincial Collegiate Programming Contest - Codeforces

A.Orders

题解:

排序+遍历

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pi;
const ll mod=100000007;
vector<pi>a;
int T,n,k;
ll x,y;
ll sum,res;
int tmp;
int main(){
	scanf("%d",&T);
	
	while(T--){
		a.clear();
		scanf("%d%d",&n,&k);
		for(int i=1;i<=n;i++){
			scanf("%lld%lld",&x,&y);
			a.push_back({x,y});
		}sort(a.begin(),a.end());
		res=k;
		int cnt=1,f=1;
		for(int i=0;i<n;i++){
			res-=a[i].second;
			if(a[i].first>cnt){
				res+=(a[i].first-cnt)*k;
				cnt=a[i].first;
			}//printf("i%d a[i]%d cnt%d res%lld\n",i,a[i].second,cnt,res);
			if(res<0){
				f=0;break;
			}
		}if(f)printf("Yes\n");
		else printf("No\n");
	}
	return 0;
}

D. Fast and Fat(二分+贪心)

题解:

weight为第一关键字,speed为第二关键字排序,二分最大值,check函数判断可否满足最大值为x,遍历所有人,将速度>=x分为c组,<x分为b组,看c组的能否带着b组

*二分起点 l,r 为初始最大最小值

*结束条件为 l<=r

*反向迭代器删除元素(++itc).base() 反向迭代器删除元素-CSDN博客

*看c组能否带着b组时从体重从大到小看

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pi;
const int inf=1<<30;
const ll mod=100000007;
vector<pi>a,c;
vector<int>b;
int T,n,k;
int v,w;
int mx,mn;
int chk(int x){//最大值为x是否可行 
	//printf("x%d\n",x);
	b.clear();c.clear();
	for(int i=0;i<n;i++){
		//printf("a[i].s:%d\n",a[i].second);
		if(a[i].second<x)b.push_back(a[i].first);
		else c.push_back(a[i]);
	}int lb=b.size(),lc=c.size();
	if(lb>lc)return 0;
	//printf("lb%d lc%d\n",lb,lc);
	
	auto itb=b.rbegin();
	for(;itb!=b.rend();itb++){
		//printf("b:%d\n",*itb);
		int flag=0;
		for(auto itc=c.rbegin();itc!=c.rend();itc++){
			//printf("cw:%d cs:%d %d\n",itc->first,itc->second,itc->second+itc->first-*itb);
			if((itc->second+itc->first-*itb)>=x){
				c.erase((++itc).base());
				flag=1;
				break;
			}
		}if(flag==0)return 0;
	}return 1;
}
int main(){
	scanf("%d",&T);
	
	while(T--){
		mx=0,mn=inf;
		a.clear();
		scanf("%d",&n);
		for(int i=1;i<=n;i++){
			scanf("%d%d",&v,&w);
			a.push_back({w,v});
			mx=max(mx,v);
			mn=min(mn,v);
		}sort(a.begin(),a.end());//按weight,speed升序排序 
		int l=mn,r=mx,res=mn;
		while(l<=r){
			int mid=(l+r)/2;
			if(chk(mid))l=mid+1,res=mid;
			else r=mid-1;
		}printf("%d\n",res);
	}
	return 0;
}

G. Matching 

*等式变换

*求取最大值时考虑负数

*考虑是否有孤立点 

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pi;
const int inf=1<<30;
const ll mod=1e9+7;
int T,n,x;
ll res;
/*
	ai-i=aj-j
	<ai-i,<ai1,ai2,...>>
*/
unordered_map<int,vector<int>>mp;
int main(){
	scanf("%d",&T);
	while(T--){
		res=0;
		scanf("%d",&n);
		mp.clear();
		for(int i=1;i<=n;i++){
			scanf("%d",&x);
			mp[x-i].push_back(x);
		}for(auto i:mp){
			vector<int>a=i.second;
			sort(a.begin(),a.end());
			for(int j=a.size()-1;j>=1;j-=2){
				if((a[j]+a[j-1])>0)res+=a[j]+a[j-1];
				else break;
			}
		}printf("%lld\n",res);
	}
	return 0;
}

I.Three Dices

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pi;
const int inf=1<<30;
const ll mod=100000007;

int a,b;
int chk(int a,int b){
	if(a>12||b>18)return 0;
	/*
		4+4+4=12
		4+4+1=9
		4+1+1=6
		1+1+1=3
		4+4=8
		4+1=5
		1+1=2
		4
		1
	*/
	if(a!=0&&a%3==0&&b==0)return 1;
	if((a==8||a==5||a==2)&&(b==2||b==3||b==5||b==6))return 1;
	/*
		6+6=12
		6+5=11
		6+3=9
		6+2=8
		5+5=10
		5+3=8
		5+2=7
		3+3=6
		3+2=5
		2+2=4
		4<=b<=12
	*/
	if(a==4&&(4<=b&&b<=12))return 1;
	if(a==1&&(4<=b&&b<=12))return 1;
	/*
		6+6+6=18
		6+6+5=17
		6+6+3=15
		6+6+2=14
		6+5+5=16
		6+5+3=14
		6+5+2=13
		6+3+3=12
		6+3+2=11
		6+2+2=10
		5+5+5=15
		5+5+3=13
		5+5+2=12
		5+3+3=11
		5+3+2=10
		5+2+2=9
		3+3+3=9
		3+3+2=8
		3+2+2=7
		2+2+2=6
		6<=b<=18
	*/
	if(a==0&&(6<=b&&b<=18))return 1;
	return 0;
}
int main(){
	scanf("%d%d",&a,&b);
	if(chk(a,b))printf("Yes");
	else printf("No");
	return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值