Codeforces Round 890 (Div. 2) supported by Constructor Institute ABCD

A. Tales of a Sort

选出最大的非递增区间的最大数即可,如果没非递增区间,则输出0

#include <bits/stdc++.h>
using namespace std;
void solve()
{
	int n,minn=1e9,sum=0,ans=0,maxx=0,flag=0;
	cin>>n;
	vector<int> a(n+1);
	for (int i=1;i<=n;i++) 
	{
		cin>>a[i];
		
	}
	for (int i=2;i<=n;i++)
	{
		if (a[i]<a[i-1])
		{
			maxx=max(maxx,a[i-1]);
			flag=1;
		}
		
	}
	if (!flag)
		cout<<0<<'\n';
	else
		cout<<maxx<<'\n';
}
int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while (t--)
		solve();
	return 0;
}

B. Good Arrays

统计1的数量cnt和大于1的数的总和sum,只要满足sum-(n-cnt)>=cnt即可,只有出现1补不上了或者n==1才判no;

#include <bits/stdc++.h>
using namespace std;
void solve()
{
	long long n,flag=1,cnt=0,sum=0;
	map<int,int> ma;
	cin>>n;
	vector<int> a(n+1);
	for (int i=1;i<=n;i++)
	{
		cin>>a[i];
		if (a[i]==1) cnt++;
		else sum+=a[i]-1;
	}
	if (n==1)
		puts("NO");
	else if (sum>=cnt)
		puts("YES");
	else
		puts("NO");
}
int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while (t--)
		solve();
	return 0;
}

C. To Become Max

二分答案,由于数据量不大,n^2*logn的做法可以实现,细节看代码注释

#include <bits/stdc++.h>
using namespace std;
void solve()
{
	int n,k,Max=0;
	cin>>n>>k;
	vector<int> a(n+1),mini(n+1);
	for (int i=1;i<=n;i++)
	{
		cin>>a[i];
		Max=max(Max,a[i]);
	}
	Max+=k;//答案的最大值
	int l=0,r=Max,ans;
	while (l<r)
	{
		int mid=(l+r+1)>>1,flag=0;

		for (int i=1;i<=n;i++)
		{
			mini[i]=mid;//当前从第i个位置开始的最大值
			long long cost=0;//已经花费的操作次数
			for (int j=i;j<=n;j++)
			{
				if (mini[j]<=a[j]) break;//比当前小说明可以有更大的答案等着二分
				if (j==n)//如果遍历到了最后,说明mini[n]>a[n],但是最后一位是不能动的,直接判错
				{
					cost=k+1;
					break;
				}
				cost+=mini[j]-a[j];
				mini[j+1]=max(0,mini[j]-1);
                //下一位的最大值是这一位的最大值减一,注意可能为零的情况
				if (cost>k) break;
			}
			if (cost<=k)
				flag=1;
		}
		if (flag) l=mid;
		else r=mid-1;
	}
	cout<<r<<'\n';
}
int main()
{
	int t;
	cin>>t;
	while (t--)
		solve();
	return 0;
}

D. More Wrong

令f(l,r)为区间[l,r]上最大的数,inv(l,r)为区间[l,r]上的逆序数,如果inv(l,r)==inv(l,r-1),则有f(l,r)=r,只有之前区间加上的数是该区间最的大的数才能不影响之前的区间的逆序数,我们可以通过分治,先从只有一个数的区间开始,然后开始合并,每个区间的状态都由其最大值表示,最终一定可以得到f(1,n)

#include <bits/stdc++.h>
using namespace std;
int query(int l,int r)
{
	if (l==r) return 0;
	cout<<"? "<<l<<' '<<r<<endl;
	int res;
	cin>>res;
	return res;
}
int getans(int l,int r)
{
	if (l==r) return l;
	int mid=(l+r)>>1;

	int a=getans(l,mid);
	int b=getans(mid+1,r);

	int qj1m=query(a,b);
	int qj2m=query(a,b-1);

	if (qj1m==qj2m) return b;
	else return a;
}
void solve()
{
	int n;
	cin>>n;
	int ans=getans(1,n);
	cout<<"! "<<ans<<endl;
}
int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while (t--)
		solve();
	return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值