Codeforces1300C. Anu Has a Function D几何 对称图形 E 2100 单调栈

给n个数,两个数之间相或,后减去后一个数,求如何排序,使得最终结果越大。
发现只要找出一个最优的数后,其余数顺序任意,因为,一旦有两个数,同时有1出现在同一位上,则不论如何计算该位必为0。
第一个数,应为在所有数中,二进制单独只为1,所表示的10进制数最大,即为最优解。
没有只有一位1有个1的话 输出原顺序

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
const double eps=1e-10;
const ll mod=1e9+7;
#define endl '\n'
ll T,n,k,q,a[maxn],dp[maxn];
void f(ll x){
	ll cnt=0;
	while(x){
		if(x&1){
			dp[cnt]++;
		}
		cnt++;
		x/=2;
	}
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		f(a[i]);
	}
	for(int i=30;i>=0;i--){
		if(dp[i]==1){
			for(int j=1;j<=n;j++){
				if((a[j]/(1<<i))&1){
					cout<<a[j]<<" ";
					for(int k=1;k<=n;k++){
						if(k!=j)
							cout<<a[k]<<" ";
					}
					cout<<endl;
					return 0;
				}
			}
		}
	}
	for(int i=1;i<=n;i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
	return 0;
}

https://codeforces.com/contest/1300/problem/D
使得P T相似 只能偶数个点的对称图形
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
const double eps=1e-10;
const ll mod=1e9+7;
#define endl '\n'
ll T,n,k,q,a[maxn],b[maxn],f;

int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i]>>b[i];
	}
	if(n&1)	//P T相似 偶数个点 对称图形 
		cout<<"NO"<<endl;
	else{
		ll dx=a[1]+a[1+n/2],dy=b[1]+b[1+n/2];
		for(int i=2;i<=n/2;i++){
			if(a[i]+a[i+n/2]!=dx || b[i]+b[i+n/2]!=dy){
				f=1;
				break;
			}
		}
		if(f)
			cout<<"NO"<<endl;
		else
			cout<<"YES"<<endl;
	}
	return 0;
}

E
单调递减栈
该段第i个数的段的长度倍<=该段前缀和 top–

就是把某个区间的数字都变成这个区间数字和的平均数,可以操作多次,问最小的字典序。’

4
7 5 5 7

5.666666667
5.666666667
5.666666667
7.000000000

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
double a[maxn],s[maxn];
ll n,st[maxn];
int main(){
	
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lf",&a[i]);
		s[i]=s[i-1]+a[i];
	}
	ll top=1;
	st[top]=0;
	for(int i=1;i<=n;i++){
		while(top>1 && (s[i]-s[st[top]])*(i-st[top-1])<=(s[i]-s[st[top-1]])*(i-st[top])) top--;
		st[++top]=i;//st[1]=0 st[2]=3 st[3]=4
		
	}
	for(int i=1;i<top;i++){
		double res=(s[st[i+1]]-s[st[i]])/(st[i+1]-st[i]);
		for(int j=1;j<=st[i+1]-st[i];j++){
			
			printf("%.9f\n",res);
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值