Codeforces Round #569 (Div. 2) B - Nick and Array(贪心)

在这里插入图片描述
在这里插入图片描述
题意:给定一个数组,你可以把数组的一个数ai=-ai-1,每个数只能进行一次这样的变换,问怎样变换后数组的乘积a1a2a3*…an最大,输出变换后的数组
思路:因为一个负数经过这样的变换后它的绝对值会变小,正数经变换后绝对值会增大,那么根据贪心思想就要把所有正数变成负数,看看最后乘起来的是正数的话就是最佳答案,但如果不是的话那么就有一个负数是要变成正数的,把谁变成负数代价最大呢?选绝对值最大的就行(这个可以自己证明)

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+1;
typedef long long ll;
vector<pair<ll,ll>>v;
ll a[maxn<<1],n,m,k,q,maxx=0,num[maxn<<1],b[maxn<<1],cnt=0,cns;
int main()
{
	scanf("%d %d",&n,&q);
	k=m=n;
	for(int i=1;i<=n;++i)
	scanf("%lld",&a[i]),num[i]=a[i],maxx=max(maxx,a[i]);
	if(q==0) return 0;
	v.push_back({0,0});
	ll first=a[1];
	if(a[1]!=maxx){
			for(int i=2;i<=n;++i)
	{
		v.push_back({first,a[i]});
		if(first>a[i]) num[++m]=a[i];
		else num[++m]=first,first=a[i];
			if(first==maxx) {
		k=i;break;}
	}
	}
	else k=1;
	ll t=v.size()-1;
	//for(int i=1;i<v.size();++i) cout<<v[i].first<<"sss"<<v[i].second<<endl;
	for(int i=k;i<=m;++i) b[++cnt]=num[i];
	//for(int i=1;i<=cnt;++i)  cout<<b[i]<<endl;
 
	while(q--)
	{
		scanf("%lld",&cns);
		if(cns<=t){
			printf("%lld %lld\n",v[cns].first,v[cns].second);
			continue;
		}
		cns-=t;
		printf("%lld %lld\n",maxx,(cns%(m-k)==0)?b[cnt]:b[(cns%(m-k))+1]);
	}
}
发布了39 篇原创文章 · 获赞 0 · 访问量 1074

猜你喜欢

转载自blog.csdn.net/qq_42479630/article/details/104062348