【算法每日一练】

发布于:2024-04-30 ⋅ 阅读:(26) ⋅ 点赞:(0)

蛮有意思的的一道题,最后要判断能否成为一种1~n的全排列,我最这样做的:

整个数组先排序一下。假设遍历到了i,那就判断前面b和r的个数,但是有想到了后面可能还会对前面的结果产生影响,所以就抛弃了这个想法。

然后就想:既然是一种排序,那么能不能先把这个排序确定下来呢,事实上是可以的。

做法就成了这样子:整个数组还是先排序,降序排序,然后把r放在b前面。(一会解释)

假如说现在变成了这样:

6 4 4 3 3 1(r r b r b r)

那么6可以变成6,4也可以变成5,4也可以变成4,3也可以变成3,3也可以变成2,1也可以变成1

这样就变成了6 5 4 3 2 1

但是我实际是升序来写的,因为更方便一点,还有一点就是要注意有时候可能光升序并不能判断出所有情况,还要降序再来一次,所以我reverse了一下。

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
struct node{
	int x;char c;
}a[N];
int t,n;
bool cmp(node a,node b){
	if(a.x!=b.x)return a.x<b.x;
	else return a.c<b.c;
}
int main(){
	cin>>t;
	while(t--){
		cin>>n;string s;
		for(int i=1;i<=n;i++)cin>>a[i].x;
		cin>>s;
		for(int i=1;i<=n;i++)a[i].c=s[i-1];
		sort(a+1,a+n+1,cmp);
		int f1=0;
		for(int i=1;i<=n;i++){
			if(a[i].x==i)continue;
			else if(a[i].x<i&&a[i].c=='R')continue;
			else if(a[i].x>i&&a[i].c=='B')continue;
			else {f1=1;break;}
		}
		reverse(a+1,a+1+n);
		int f2=0;
		for(int i=1;i<=n;i++){
			if(a[i].x==i)continue;
			else if(a[i].x<i&&a[i].c=='R')continue;
			else if(a[i].x>i&&a[i].c=='B')continue;
			else {f2=1;break;}
		}
		if(f1==0||f2==0)cout<<"YES\n";
		else cout<<"NO\n";
	}
	return 0;
}

        

        

这个题肯定是要排序的(根据直觉),那么最好是按照人数要求来降序排序,这样的话遍历到当前的人的要求时候,就不需要再考虑前面的那么人了。

所以我们先排序,然后一次遍历每个人,如果当前的人数要求满足就直接放进来,如果不满足就看情况来踢掉当前队伍中战力最低的人。所以我们还需要一个优先级队列优化。

还有一点需要注意:

在队伍放入两个人后:总战力是60,人数是2

再遍历第三个人的时候,发现人数过多,那么就应该踢掉一个人,此人战力20小于120,所以这个人就踢掉,然后还需要踢一个人,比较此人的战力40小于120,所以也踢掉。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+5;
struct node{
	ll A,B;
//	bool operator>(const node &b)const {return A>b.A;}
}a[N];
bool operator>(const node &a,const node &b){
	return a.A>b.A;
}
ll ans,n,sum;
priority_queue<node,vector<node>,greater<node> >q;
bool cmp(node a,node b){
	return a.B>b.B;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i].A>>a[i].B;
	sort(a+1,a+1+n,cmp);
	for(int i=1;i<=n;i++){
		q.push(a[i]);
		sum+=a[i].A;
		while(q.size()>a[i].B){
			sum-=q.top().A;
			q.pop();
		}
		ans=max(ans,sum);
	}
	cout<<ans;
	return 0;

	return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到