2024 暑假友谊赛 1


A - 😜

096 - Cooking

动态规划,简单的动态规划,但是不会写。

m=\sum {_{}Ti}^{}
dp 的状态转移⽅程为 f[i][j] 表示前 i 个菜肴,占⽤第⼀个烤箱时⻓为 j 的⽅案是否存在。

 

#include<bits/stdc++.h>
using namespace std;
#define int  long long
#define endl '\n'
#define inf 0x3f3f3f3f
#define pii pair<int,int>

void solve(){
	int t[101];
	int total=0,n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>t[i];
		total+=t[i];
	}
	vector<vector<bool>>dp(n+10,vector<bool>(total+1,false));
	dp[1][0]=true;//第一个食物不存在第一个烤箱里的情况存在。
	dp[1][t[0]]=true;//存在第一个烤箱里的情况存在。
	for(int i=1;i<=n;i++){
		for(int j=0;j<=total;j++){
			if(dp[i][j]){//如果这个方案可以存在。
				dp[i+1][j]=true;
				//那么下一个食物存在第二个烤箱里的方案可以存在。
				dp[i+1][j+t[i]]=true;
				//下一个食物还存第一个烤箱里的方案也可以存在。
			}
		}
	}
	int ans=total;
	for(int i=0;i<=total;i++){
		if(dp[n+1][i]){//枚举第N个食物存完后可能的情况。
			ans=min(ans,max(i,total-i));
			//取当前两个烤箱时间的最大值。再和ans取min
		}
	}
	cout<<ans<<endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
	//cin>>oyyo;
	
	while(oyyo--) {
		solve();
	}
	return 0;
}

 B - 😭

C - 2D Plane 2N Points

对所有的点按最靠近原点与否进行排序,然后对于B中每个点,从A中找与他最相近的,把这个点标记出来,下次遍历就不需要了。点的排列有一些怪。要调好多次。

#include<bits/stdc++.h>
using namespace std;
#define int  long long
#define endl '\n'
#define inf 0x3f3f3f3f
#define pii pair<int,int>

struct dian{
	int x,y;
};

bool cmp(dian a,dian b){
	if(a.x==b.x){
		return a.y<b.y;
	}
	return a.x<b.x;
}
void solve(){
	int n;
	cin>>n;
	vector<dian>a(n),b(n);
	vector<int>biao2(n+1,0);
	for(int i=0;i<n;i++){
		cin>>a[i].x>>a[i].y;
	}
	for(int i=0;i<n;i++){
		cin>>b[i].x>>b[i].y;
	}	
	int sum=0;
	sort(a.begin(),a.end(),cmp);
	sort(b.begin(),b.end(),cmp);

		for(int i=0;i<n;i++){
			int ff=0,aa=-1;
			for(int j=0;j<n;j++){
				if(a[j].x<b[i].x and a[j].y<b[i].y and biao2[j]==0){
					ff++;
					if(ff==1){
						aa=j;
					}else{
						if(a[j].y>a[aa].y){
							aa=j;
						}
					}
				}
			}
			if(aa!=-1){
				biao2[aa]=1;
				sum++;
			}
		}
	
	cout<<sum<<endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
	//cin>>oyyo;
	
	while(oyyo--) {
		solve();
	}
	return 0;
}

如果是对于A中的点,去找B里和他最接近的点的话:y要从小到大,x要从大到小。

#include<bits/stdc++.h>
using namespace std;
#define int  long long
#define endl '\n'
#define inf 0x3f3f3f3f
#define pii pair<int,int>

struct dian{
	int x,y;
};

bool cmp(dian a,dian b){
	if(a.x==b.x){
		return a.y<b.y;
	}
	return a.x>b.x;
}

void solve(){
	int n;
	cin>>n;
	vector<dian>a(n),b(n);
	vector<int>biao2(n+1,0);
	for(int i=0;i<n;i++){
		cin>>a[i].x>>a[i].y;
	}
	for(int i=0;i<n;i++){
		cin>>b[i].x>>b[i].y;
	}	
	int sum=0;
	sort(a.begin(),a.end(),cmp);
	sort(b.begin(),b.end(),cmp);
	
	for(int i=0;i<n;i++){
		int ff=0,aa=-1;
		for(int j=0;j<n;j++){
			if(a[i].x<b[j].x and a[i].y<b[j].y and biao2[j]==0){
				ff++;
				if(ff==1){
					aa=j;
				}else{
					if(b[j].y<b[aa].y){
						aa=j;
					}
				}
			}
		}
		if(aa!=-1){
			biao2[aa]=1;
			sum++;
		}
		
	}
	
	
	cout<<sum<<endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
	//cin>>oyyo;
	
	while(oyyo--) {
		solve();
	}
	return 0;
}

H - 

A - Apple

成功签到。先算货币价值,如果单个Y/3可以买的苹果大于1个,就优先用Y货币买到剩余数量不足3个,再用X货币扫尾,否则直接用X货币买完。

#include<bits/stdc++.h>
using namespace std;
#define int unsigned long long
#define endl '\n'
#define inf 0x3f3f3f3f
#define pii pair<int,int>

void solve(){
	int x,y,n;
	cin>>x>>y>>n;
	double q1=x;
	double q2=y/3;
	if(q1<=q2){
		cout<<x*n<<endl;
	}else{
		int z=n/3;
		int sum1=z*y;
		int sum2=(n%3)*x;
		cout<<sum1+sum2<<endl;
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
	//cin>>oyyo;
	
	while(oyyo--) {
		solve();
	}
	return 0;
}

D - 😓

D - Cake 123

数据范围虽然很小,但是实在是想不到这样来保障数据范围,写了100多行垃圾。

首先肯定要对三个数组所有数进行排序,然后枚举情况:

if((i+1)*(j+1)*(k+1)<=kk)

将所有符合的情况都塞进去,然后排序输出前kk个就好了

#include<bits/stdc++.h>
using namespace std;
#define int  long long
#define endl '\n'
#define inf 0x3f3f3f3f
#define pii pair<int,int>

bool cmp(pair<int,char> a,pair<int,char> b){
	return a.first>b.first;
}

void solve(){
	
	int x,y,z;
	cin>>x>>y>>z;
	int kk;
	cin>>kk;
	vector<int>a(x),b(y),c(z);
	for(int i=0;i<x;i++){
		cin>>a[i];
	}
	for(int i=0;i<y;i++){
		cin>>b[i];
	}
	for(int i=0;i<z;i++){
		cin>>c[i];
	}
	sort(a.begin(),a.end());
	sort(b.begin(),b.end());
	sort(c.begin(),c.end());
	reverse(a.begin(),a.end());
	reverse(b.begin(),b.end());
	reverse(c.begin(),c.end());
	vector<int>jie;
	for(int i=0;i<x;i++){
		for(int j=0;j<y;j++){
			for(int k=0;k<z;k++){
				if((i+1)*(j+1)*(k+1)<=kk){
					jie.push_back(a[i]+b[j]+c[k]);	
				}
			}
		}
	}
	sort(jie.begin(),jie.end());
	reverse(jie.begin(),jie.end());
	
	for(int i=0;i<kk;i++){
		cout<<jie[i]<<endl;
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cout.tie(nullptr);
	int oyyo=1;
	//cin>>oyyo;
	
	while(oyyo--) {
		solve();
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值