凉心的比赛(一)补题

题目链接

D*Well played!

题意:有n个物品,能进行a次操作一和b次操作二,每个物品有一个hp和damage,操作一为把某个物品的hp变为原来的两倍,操作二为把某个物品的hp赋值给它的damage,问这n个物品的damage的总和最大是多少。

思路:证明出来a操作应该都使用给同一个物品最优,然后按b操作的最优方案排序,枚举使用a操作

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<map>
#include<algorithm>
#include<queue>
#include<math.h>
#include<vector>
using namespace std;
#define Inf 0x7fffffff
typedef long long ll;
const int N=220000;
int n,a,b;
struct node{
	ll hp,dmg,x;
}f[N];
ll ans,s;
int cmp(node x,node y){return x.x>y.x;}
	
int main(){
	cin>>n>>a>>b;
	for(int i=1;i<=n;i++){
		scanf("%lld%lld",&f[i].hp,&f[i].dmg);
		f[i].x=f[i].hp-f[i].dmg;
	}
	sort(f+1,f+1+n,cmp);
	ll sum=0;
	for(int i=1;i<=b;i++)sum+=max(f[i].hp,f[i].dmg);
	for(int i=b+1;i<=n;i++)sum+=f[i].dmg;
	ans=sum;
	for(int i=1;i<=b;i++)ans=max(ans,sum-max(f[i].hp,f[i].dmg)+(f[i].hp<<a)); 
	sum=sum-max(f[b].hp,f[b].dmg)+f[b].dmg;
	for(int i=b+1;i<=n&&b;i++)ans=max(ans,sum-f[i].dmg+(f[i].hp<<a));
	cout<<ans;
}

G*法法非法是朋友

题意:通过圆心坐标(x1,y1)和半径R给定一个大的圆形范围和一个点(x2,y2),找一个圆形范围使其不包含点(x2,y2)和大圆外任意点。

思路:找内切圆,半径为 dis[(x1,y1),(x2,y2)]+R
注意:若(x1,y1)和(x2,y2)重合,不包含点(x2,y2)的最大内切圆的半径只能为R/2

#include<bits/stdc++.h>
using namespace std;
#define Inf 0x7fffffff
typedef long long ll;
double x1,x2,y1_,y2_,R,r,x,y;
double dis(double x1,double y1_,double x2,double y2_){
	return sqrt((x1-x2)*(x1-x2)+(y1_-y2_)*(y1_-y2_));
}
int main(){
	cin>>R>>x1>>y1_>>x2>>y2_;
	double d=dis(x1,y1_,x2,y2_);
	if(d>=R){
		//cout<<x1<<" "<<y1_<<" "<<R;
		printf("%.1lf %.1lf %.1lf",x1,y1_,R);
		return 0;
	}
	if(d==0){
		printf("%.16lf %.16lf %.16lf",x1+R/2,y1_,R/2);
		return 0;
	}
	r=d+R;
	x=x2+(x1-x2)/d*r;
	y=y2_+(y1_-y2_)/d*r;
	x=(x+x2)/2;y=(y+y2_)/2;
	r/=2;
	printf("%.16lf %.16lf %.16lf",x,y,r);
}
发布了17 篇原创文章 · 获赞 7 · 访问量 2072

猜你喜欢

转载自blog.csdn.net/qq_45530271/article/details/103934593