Codeforces Round 892 (Div. 2) 题解

A.United We Stand

要求把数组 a 划分成数组 b,c,数组 c 中的元素不能被数组 b 整除,所以把最大的(注意可能有多个相同

元素最大)放入c,然后其余的放入 b 即可。

赛时代码:

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n;
long long a[105];
void solve()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
    	cin>>a[i];
	}
	sort(a+1,a+n+1);
	if(a[1]==a[n])
	{
		cout<<-1<<endl;
		return;
	}
	int cnt=0;
	for(int i=n;i>=1;i--)
	{
		if(a[i]!=a[n])
		{
			cnt=i;
			break;
		}
	}
	cout<<cnt<<" "<<n-cnt<<endl;
	for(int i=1;i<=cnt;i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
	for(int i=cnt+1;i<=n;i++)
	{
		cout<<a[i]<<" ";
	}
	cout<<endl;
}
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		solve();
	}
}

B.Olya and Game with Arrays

通过一些简单的思考发现每个数组中只有最小项和次小项对结果有贡献,找到最小项,然后外加(n-1)个较

大的次小项即可。

赛时代码:

点击查看代码
#include<bits/stdc++.h>
using namespace std;
map<int,int>mp;
long long a[50005],b[50005],c[50005];
void solve()
{
	int n;
	long long ans=0;
	cin>>n;
	if(n==1)
	{
		int num;
		cin>>num;
		for(int i=1;i<=num;i++)
		{
			cin>>a[i];
		}
		sort(a+1,a+num+1);
		cout<<a[1]<<endl;
		return;
	}
	else
	{
		for(int i=1;i<=n;i++)
		{
			int num;
			cin>>num;
			for(int j=1;j<=num;j++)
			{
				cin>>a[j];
			}
			sort(a+1,a+num+1);
			b[i]=a[1],c[i]=a[2];
		}
		sort(b+1,b+n+1);
		ans+=b[1];
		sort(c+1,c+n+1);
		for(int i=n;i>=2;i--)
		{
			ans+=c[i];
		}
		cout<<ans<<endl;
		return;
	}
}
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		solve();
	}
}

C.Another Permutation Problem

对于一个排列,前面的全部正序,后面的全部倒序,n 的范围很小,从小到大枚举倒序的长度即可。

(ps:这个想法没有经过严格的证明。)

赛时代码:

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n;
long long a[255];
bool cmp(int x,int y)
{
	return x>y;
}
void ini()
{
	for(int i=1;i<=n;i++)
	{
		a[i]=i;
	}
}
void solve()
{
	cin>>n;
	ini();
	if(n==2)
	{
		cout<<2<<endl;
		return;
	}
	else if(n==3)
	{
		cout<<7<<endl;
		return;
	}
	long long ans=0,fans=0,Max=0;
	for(int k=2;k<=n;k++)
	{
		sort(a+n-k+2,a+n+1,cmp);
		for(int i=1;i<=n;i++)
		{
			ans+=a[i]*i;
			Max=max(Max,a[i]*i);
		}
		ans-=Max;
		if(ans>fans)
		{
			fans=ans;
			ini();
			ans=0;
			Max=0;
		}
		else
		{
			cout<<fans<<endl;
			return;
		}
	}
}
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		solve();
	}
}

D.Andrey and Escape from Capygrad

对包含 l,r,a,b 的结构体 A 按照 b 从小到大进行排列,关键要存储和更新每个节点的 l 和 b,

补题代码:

点击查看代码
#include<bits/stdc++.h>
using namespace std;
map<int,int>mp;
int n,q,x;
int read(){
	int ans=0,f=1;
	char ch=getchar();
	while(!isdigit(ch)){
		f*=(ch=='-')?-1:1;
		ch=getchar();
	}
	while(isdigit(ch)){
		ans=ans*10+ch-'0';
		ch=getchar();
	}
	return ans*f;
}

struct node
{
	int l,r,a,b;
}A[200005];
inline bool operator<(const node&p,const node&q)
{
	return p.b<q.b;
}
void solve()
{
	mp.clear();
	n=read();
	for(int i=1;i<=n;i++)
	{
		A[i]={read(),read(),read(),read()};
	}
	sort(A+1,A+n+1);
	int la=A[n].l,fa=A[n].b;
	for(int i=n-1;i>=1;i--)
	{
		if(A[i].b<la)
		{
			mp[la]=fa;la=A[i].l,fa=A[i].b;
		}
		else
		{
			la=min(la,A[i].l);
		}
	}
	mp[la]=fa;
	q=read();
	while(q--)
	{
		x=read();
		auto it=mp.upper_bound(x);
		if(it==mp.begin()||it==mp.end()) printf("%d ",x);
		else
		{
			it--;
			int tmp=max(x,it->second);
			printf("%d ",tmp);
		}
	}
	printf("\n");
	return;
}
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		solve();
	}
}
posted @ 2023-08-14 14:52  ataraxyyeah  阅读(62)  评论(0)    收藏  举报