Day4总结

· 2026-7-13 19:06:32

T1 题目:有n名选手,a[i]为选手的大小,两两之间n-1次比赛,大的打败小的后吃掉小的,一样则随机一方胜利。求可能获胜的选手。

思路:对于每一个选手,都应该击败所有小于等于他初始数值的选手,所以他在遇到比他初始数值大的选手之前最大的数值就是所有<=他的加上他本身。

所以先从小往大排序,再求前缀和数组s

对于每个i,若不存在a[j]>sumj-1,则a[i]所对应的选手是可能赢的。

如果找到一个这样的i,那么他后面的都满足这个条件,输出即可。

T2

两台电视看一堆节目,结束越早的节目排在越前面,给后面留出更多空间。两次处理后,看是不是所有节目都看了,按题意输出。

T3和T6

题目:

有n个药水排成一行,药水1在最左边,药水n在最右边。每个药水喝下后会使你的生命值增加ai​。ai可能为负数,表示该药水会减少你的生命值。

你初始时生命值为0,并且你会从左到右依次经过每个药水。每到一个药水处,你可以选择喝下它或者忽略它。你必须保证你的生命值始终不为负数。

你最多能喝下多少瓶药水?

思路:初始化ans为n,就是首先假设所有药水都喝下去了。

从左往右遍历,先喝下药水,再把这次的药水放进小根堆中。判断是否<0.若<0,则从小根堆中取出最小的,把当前生命值减去最小值,

且ans--。小根堆抛掉栈顶。

ans就是答案。

T4:

题目:给长度为n的数组a,b,求(ai-bi)^2的和。操作可以对任意ai,bi加1或减1.

分析:减小(a-b)^2相当于减小abs(a-b). 削减7就比削减5有价值,削减越大的数越有价值。所以开大根堆处理。

(a-b-1)=(a-1-b),所以k1和k2都一样。

循环k1+k2次,每一次都取出堆顶元素,-1后取绝对值再放入堆中。

T5:

题目:歌单最长为k,好听程度=(歌单中所有歌曲长度的和)*所有歌曲中最小的美丽度。

分析:首先按歌曲的美丽度从大到小排序. i:1~n,歌从1~i中选。每轮的最小美丽度为a[i]的最小美丽度(因为是按美丽度从大往小排序的)

最小美丽度固定,要最大化歌单中所有歌曲长度的和,则利用大根堆求1~i中前k大的歌,求和再相乘,求max。

最后最大的就为答案。

T6见T3.

T1代码:

#include<bits/stdc++.h>
using namespace std;
int t,n;
struct node{
	int id;
	long long val;
}a[200005];
long long s[2000005];
bool cmp(node x,node y){
	return x.val<y.val;
}
bool cmp1(node x,node y){
	return x.id<y.id;
}
int main(){
cin>>t;
while(t--){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i].val;
		a[i].id=i;
	}
	sort(a+1,a+1+n,cmp);
    int d=n;
    for(int i=1;i<=n;i++){
        s[i]=s[i-1]+a[i].val;
    }
    for(int i=n;i>=1;i--){
        if(a[i].val>s[i-1]){
            d=i;
            break;
        }
    }
    sort(a+d,a+n+1,cmp1);
    cout<<n-d+1<<"\n";
    for(int i=d;i<=n;i++){
        cout<<a[i].id<<" ";
    }
    cout<<"\n";
}
	return 0;
}

T2代码:
#include<bits/stdc++.h>
using namespace std;
struct node{
	int l,r;
}a[200005]; 
int n;
int vis[200005]; 
bool cmp(node a,node b){
	return a.r<b.r;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)scanf("%d%d",&a[i].l,&a[i].r);
	sort(a+1,a+1+n,cmp);
	int last=0;
	for(int i=1;i<=n;i++){
		if(a[i].l>last){
			vis[i]=1;
			last=a[i].r;
		}
	}
	last=0;
	for(int i=1;i<=n;i++){
		if(!vis[i]&&a[i].l>last){
			vis[i]=1;
			last=a[i].r;
		}
	}
	for(int i=1;i<=n;i++){
		if(!vis[i]){
			cout<<"NO";
			return 0;
		}
	}
	cout<<"YES";
	return 0;
} 
T3和T6代码:
#include<bits/stdc++.h>
using namespace std;
int n;
int a[200005];
struct cmp{
	bool operator()(const int& x,const int& y){
		return a[x]>a[y];
	}
};
priority_queue<int,vector<int>,cmp>q;
long long sum=0;
int main(){
	cin>>n;
	int ans=n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum+=a[i];
		q.push(i);
        //cout<<a[q.top()]<<"\n";
		if(sum<0){
			int tmp=q.top();
			sum-=a[tmp];
			q.pop();
			ans--;
		}
	}
	cout<<ans;
	return 0;
}

T4代码:
#include<bits/stdc++.h>
using namespace std;
int n,k;
int k1,k2;
int a[1005],b[1005];
int c[1005],d[1005];
bool cmp(int x,int y){
	return x>y;
}
long long ans=0;
priority_queue<int,vector<int>,less<int> >q;
int main(){
	cin>>n>>k1>>k2;
	k=k1+k2;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=n;i++){
		cin>>b[i];
		c[i]=abs(a[i]-b[i]);
		q.push(c[i]);
	}
    while(k){
        k--;
        int tmp=q.top();
        q.pop();
        q.push(abs(tmp-1));
    }
    while(q.size()){
        ans+=(long long)q.top()*q.top();
        q.pop();
    }
	cout<<ans;
	return 0;
}


T5代码:
#include<bits/stdc++.h>
using namespace std;
int n,k;
struct node{
	int t,b;
}a[300005];
bool cmp(node x,node y){
	return x.b>y.b;
}
long long Ans=-1;
priority_queue<int>q;
int main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>a[i].t>>a[i].b;
	}
	sort(a+1,a+1+n,cmp);
	for(int i=1;i<=n;i++){
		long long sum=0;
		q.push(a[i].t);
		int p=k;
		long long times=a[i].b;
		vector<int>arr;
		while(q.size()&&p){
			p--;
			sum+=(long long)q.top();
			arr.push_back(q.top());
			q.pop();
		}
		Ans=max(Ans,times*sum);
		for(int i=0;i<arr.size();i++){
			q.push(arr[i]);
		}
	}
	cout<<Ans;
	return 0;
}
已修改 4 次查看 举报

0 条评论

目前还没有评论...

Be the first to comment!

返回讨论列表
徐廷蔚
107
通过题目
10
发帖数