其他分享
首页 > 其他分享> > BUPT 2021 Winter Training #11

BUPT 2021 Winter Training #11

作者:互联网

链接:https://vjudge.net/contest/481321#overview

A - Toda 2

题意

一群玩dota的人想组个战队,然而他们的段位良莠不齐,于是决定组队掉分掉到所有人段位一样为止。由于某种原因,他们不能单人掉分,只能选择从双排到五排的多人掉分。每打一局所有人段位-1.请问他们能达到相同段位的最大值是多少,并输出整个掉分方案。

人话:n个数,每次可以从中任选2到5个同时-1.经过一些步骤后n个数全部相等,问这个相等的数最大是多少,并输出每个步骤。

思路

首先,可以简化为删除个数只有2和3,因为4和5可以由2和3组成。
显然若最大值出现了不止一次,那么从最大值开始一层一层删,因为2和3可以组成大于等于2的任意整数。
如果最大值只出现了一次,那么首先一定会把最大值删到和次大值相等。且这个过程不能动次大值,不动次大值一定必动次大值更优。那么一定先进行最大值-次大值次删2操作,其中一个删最大值,另外一个在最大值和次大值之外的值尽量平均地删。
删到最大值和次大值相等后就变成上一种情况了,继续操作即可。

代码
#include<cstdio>
#include<algorithm>
using namespace std;
int n;
struct st1{
	int x;
	int num;
}lis[110];
int totans[10010][110],cnt=0;
int minimum;

bool cmp(st1 a,st1 b)
{
	return a.x>b.x;
}
void oper_last1()//can
{
	
	int k,i,j;
	int a,b,c;
	
	/*printf("******\n");
	for(k=1;k<=n;k++)printf("%d ",lis[k].x);
	printf("\n");*/
	
	c=lis[1].x-lis[n].x;
	
	for(k=0;k<c;k++)
	{
		for(i=1;i<=n;i++)if(lis[i].x!=lis[1].x)break;
		a=i-1; b=1;
		if(a&1)
		{
			cnt++;
			for(i=1;i<=n;i++)
			{
				if(i==lis[1].num || i==lis[2].num || i==lis[3].num)totans[cnt][i]=1;
				else totans[cnt][i]=0;
			}
			b=4;
		}
		while(b<a)
		{
			cnt++;
			for(i=1;i<=n;i++)
			{
				if(i==lis[b].num || i==lis[b+1].num)totans[cnt][i]=1;
				else totans[cnt][i]=0;
			}
			b+=2;
		}
		for(i=1;i<=a;i++)lis[i].x--;
		/*printf("******\n");
		for(i=1;i<=n;i++)printf("%d ",lis[i].x);
		printf("\n");*/
	}
	minimum=lis[n].x;
	return;
}
void oper_last2()//can't
{
	int k,i,j;
	for(k=0;k<lis[1].x;k++)
	{
		cnt++;
		for(i=1;i<=n;i++)
		{
			if(i==lis[1].num || i==lis[2].num)totans[cnt][i]=1;
			else totans[cnt][i]=0;
		}
	}
	minimum=0;
	return;
}
int find_pos()
{
	int k,i,j;
	for(k=n-1;k>2;k--)if(lis[k].x>lis[k+1].x)return k;
	return n;
}

int main()
{
	int k,i,j;
	int a,b,c;
	scanf("%d",&n);
	for(k=1;k<=n;k++)
	{
		scanf("%d",&lis[k].x);
		lis[k].num=k;
	}
	sort(lis+1,lis+n+1,cmp);
	if(n==2)
	{
		if(lis[1].x==lis[2].x)oper_last1();
		else oper_last2();
		
		printf("%d\n%d\n",minimum,cnt);
		for(k=1;k<=cnt;k++)
		{
			for(i=1;i<=n;i++)printf("%d",totans[k][i]);
			printf("\n");
		}
		return 0;
	}
	
	c=lis[1].x-lis[2].x;
	//printf("# %d\n",c);
	for(k=0;k<c;k++)
	{
		a=find_pos();
		if(lis[a].x==0)
		{
			oper_last2();
			break;
		}
		cnt++;
		for(i=1;i<=n;i++)
		{
			if(i==lis[1].num || i==lis[a].num)totans[cnt][i]=1;
			else totans[cnt][i]=0;
		}
		lis[1].x--; lis[a].x--;
	}
	
	if(k==c)oper_last1();
	
	printf("%d\n%d\n",minimum,cnt);
	for(k=1;k<=cnt;k++)
	{
		for(i=1;i<=n;i++)printf("%d",totans[k][i]);
		printf("\n");
	}
	
	
	return 0;
}

标签:11,Training,大值,return,int,最大值,BUPT,段位,st1
来源: https://www.cnblogs.com/teralem/p/15913674.html