Codeforces Round 965 (Div. 2) (个人题解)(待补全)

前言:

今天晚上打的cf,只能说我还是太菜了,只会前两道签到题,第三题自己有一点思路但苦于时间不太够没能调出来,已经很晚了,明早还有事,我就先把写出来的题放在这,如果之后有补出来的题我再来更新吧!;

正文:

网址:Dashboard - Codeforces Round 965 (Div. 2) - Codeforces

A. Find K Distinct Points with Fixed Center:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int t;
	cin>>t;
	while(t--){
		int x,y,k;
		scanf("%d%d%d",&x,&y,&k);
		if(k%2){
			cout<<x<<" "<<y<<endl;
			int r=(k-1)/2;
			for(int i=1;i<=r;i++){
				cout<<x+i<<" "<<y+i<<endl;
				cout<<x-i<<" "<<y-i<<endl;
			}
		}
		else{
			int r=k/2;
			for(int i=1;i<=r;i++){
				cout<<x+i<<" "<<y+i<<endl;
				cout<<x-i<<" "<<y-i<<endl;
			}
		}
	}
	return 0;
} 

根据中点找k个不同的其他点,我们直接在直角坐标中求斜率为1的线的对称点即可。

B. Minimize Equal Sum Subarrays:

#include<bits/stdc++.h>
using namespace std;
int a[200005];
int main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
		}
		for(int i=2;i<=n;i++){
			printf("%d ",a[i]);
		}
		printf("%d\n",a[1]);
	}
	return 0;
}

将每个数往前移动一位输出即可。

C. Perform Operations to Maximize Score:

#include <bits/stdc++.h>
#define int long long
typedef long long ll;
const int N=2e5+5;
using namespace std;
struct Point {
	int x;  // 数组元素
	int y; // 二进制标记,表示是否可以选择该元素进行增加操作
};
bool operator<(const Point& a, const Point& b) {
	return a.x < b.x || (a.x == b.x && a.y < b.y);
}
void solve(){
	int n,k;
		scanf("%lld%lld",&n,&k);
		vector<Point> a(n + 1);
		for(int i=1;i<=n;i++)scanf("%lld",&a[i].x);
		for(int i=1;i<=n;i++)scanf("%lld",&a[i].y);
		sort(a.begin()+1,a.end());
		int ans=a[n/2].x+a[n].x;
		int tmp=0;
		if(a[n].y==1){
			printf("%lld\n",ans+k);
			return;
		}
		for(int i=n;i>=1;i--){
			if(a[i].y){
				tmp=i;
				break;
			}
		}
		int l=a[n/2].x,r=l+k;
		while(l<=r){
			int mid=(l+r)>>1;
			int all=n,cost=k;
			for(int i=n;i>0&&all>=n/2;i--){
				if(a[i].x<mid&&a[i].y){
					if(a[i].x+cost>=mid){
						cost-=mid-a[i].x;
						all--;
					}
				}
				if(a[i].x>=mid){
					all--;
				}
			}
			if(all<n/2){
				l=mid+1;
				ans=max(ans,mid+a[n].x);
			}
			else{
				r=mid-1;
			}
		}
		a[tmp].x+=k;
		sort(a.begin()+1,a.end());
		ans=max(ans,a[n/2].x+a[n].x);
		printf("%lld\n",ans);
}
signed main(){
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

题目大意是指可以对b[i]=1的数进行加1操作k次,问能得到的数组最大值和中位数的和的最大值为多少,只有两种操作思路,要么使a[n/2]最大,要么使a[n]最大。可以分别进行两种操作,最后令ans取max。易知当最大值a[n]可以操作时,将k全部加到最大值a[n]上,此时k全部有贡献,ans直接为最大ans。否则将最大可操作的值加满。中位数情况要保证中位数尽可能变大,这就要注意中位数在变大过程中可能会改变,所以我们得一直对当前的中位数操作,我们可以用二分来判断最后的中位数是多少(需要加多少),再判断此情况是否合理来更新最大值即可。

后记:

   前两道题23分钟就写完了,后面的时间直接就开始坐牢了,果然做的题还是太少了啊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值