[codeforces 1393B] Applejack and Storages 桶排序套桶排序

风流意气都作罢 提交于 2020-08-09 08:42:00

Codeforces Round #662 (Div. 2)   参与排名人数13194

[codeforces 1393B]   Applejack and Storages   桶排序套桶排序

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址https://codeforces.com/contest/1393/problem/B

Problem Lang Verdict Time Memory
B - Applejack and Storages GNU C++17 Accepted 93 ms 4700 KB

题目大意:用仓库里的木条充当矩形的边(一条边,只能由一个木条充当),要求围成一个正方形(需要4个木条),一个矩形(需要4个木条,这个矩形也可以是正方形)。仓库里的目标可以增加,也可以减少。若能围成,输出YES,若不能,输出NO.

基本思路:统计相同长度的木条数量(第一次桶排序),再对数量进行桶排序(第二次桶排序,详见代码)。针对数量进行讨论(详见代码)。

样例模拟如下:

6
1 1 1 2 1 1
6
+ 2

NO
cnt[1]=5,长度为1的木条有5根。
cnt[2]=2,长度为2的木条有2根。

num[1]=0,长度雷同数量为1的木条集合有0个。
num[2]=1,长度雷同数量为2的木条集合有1个。
num[3]=0,长度雷同数量为3的木条集合有0个。
num[4]=0,长度雷同数量为4的木条集合有0个。
num[5]=1,长度雷同数量为5的木条集合有1个。

n=7
n-(num[1]*1+num[2]*2+num[3]*3)=7-(0*1+1*2+0*3)=5,可提供给正方形的边数
5只能提供给一个正方形。
因num[2]+num[3]=1+0,只能提供给矩形两条边,构不成矩形,故输出NO.


+ 1

YES
cnt[1]=6,长度为1的木条有6根。
cnt[2]=2,长度为2的木条有2根。

num[1]=0,长度雷同数量为1的木条集合有0个。
num[2]=1,长度雷同数量为2的木条集合有1个。
num[3]=0,长度雷同数量为3的木条集合有0个。
num[4]=0,长度雷同数量为4的木条集合有0个。
num[5]=0,长度雷同数量为5的木条集合有0个。
num[6]=1,长度雷同数量为6的木条集合有1个。

n=8
n-(num[1]*1+num[2]*2+num[3]*3)=8-(0*1+1*2+0*3)=6,可提供给正方形的边数
6能提供给一个正方形,还多出6-4=2条边,提供给矩形。
因num[2]+num[3]=1+0,能提供给矩形剩下两条边,故能构成矩形,故输出YES.

- 1

NO

cnt[1]=5,长度为1的木条有5根。
cnt[2]=2,长度为2的木条有2根。

num[1]=0,长度雷同数量为1的木条集合有0个。
num[2]=1,长度雷同数量为2的木条集合有1个。
num[3]=0,长度雷同数量为3的木条集合有0个。
num[4]=0,长度雷同数量为4的木条集合有0个。
num[5]=1,长度雷同数量为5的木条集合有1个。

n=7
n-(num[1]*1+num[2]*2+num[3]*3)=7-(0*1+1*2+0*3)=5,可提供给正方形的边数
5只能提供给一个正方形。
因num[2]+num[3]=1+0,只能提供给矩形两条边,构不成矩形,故输出NO.

+ 2

NO

cnt[1]=5,长度为1的木条有5根。
cnt[2]=3,长度为2的木条有3根。

num[1]=0,长度雷同数量为1的木条集合有0个。
num[2]=0,长度雷同数量为2的木条集合有0个。
num[3]=1,长度雷同数量为3的木条集合有1个。
num[4]=0,长度雷同数量为4的木条集合有0个。
num[5]=1,长度雷同数量为5的木条集合有1个。

n=8
n-(num[1]*1+num[2]*2+num[3]*3)=8-(0*1+0*2+1*3)=5,可提供给正方形的边数
5只能提供给一个正方形。
因num[2]+num[3]=1+0,只能提供给矩形两条边,构不成矩形,故输出NO.


- 1

NO

cnt[1]=4,长度为1的木条有4根。
cnt[2]=3,长度为2的木条有3根。

num[1]=0,长度雷同数量为1的木条集合有0个。
num[2]=0,长度雷同数量为2的木条集合有0个。
num[3]=1,长度雷同数量为3的木条集合有1个。
num[4]=1,长度雷同数量为4的木条集合有1个。
num[5]=0,长度雷同数量为5的木条集合有0个。

n=7
n-(num[1]*1+num[2]*2+num[3]*3)=7-(0*1+0*2+1*3)=4,可提供给正方形的边数
4只能提供给一个正方形。
因num[2]+num[3]=0+1,只能提供给矩形两条边,构不成矩形,故输出NO.

+ 2

YES

cnt[1]=4,长度为1的木条有4根。
cnt[2]=4,长度为2的木条有4根。

num[1]=0,长度雷同数量为1的木条集合有0个。
num[2]=0,长度雷同数量为2的木条集合有0个。
num[3]=0,长度雷同数量为3的木条集合有0个。
num[4]=2,长度雷同数量为4的木条集合有2个。
num[5]=0,长度雷同数量为5的木条集合有0个。

n=8
n-(num[1]*1+num[2]*2+num[3]*3)=7-(0*1+0*2+0*3)=8,可提供给正方形的边数
8能提供给一个正方形,还剩8-4=4提供给矩形4条边。构成矩形,故输出YES.

AC代码如下:

#include <cstdio>
#include <algorithm>
using namespace std;
#define maxn 100010
int cnt[maxn],num[maxn];
char cmd[5];
int main(){
	int n,i,q,a,b,len=0;
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%d",&a),cnt[a]++,len=max(a,len);//len与n是不同的两个量
	for(i=1;i<=len;i++)num[cnt[i]]++;
	scanf("%d",&q);
	while(q--){
		scanf("%s%d",cmd,&a);
		if(cmd[0]=='+')num[cnt[a]]--,cnt[a]++,num[cnt[a]]++,n++;//num[cnt[a]]--清除更新前cnt[a]集合的统计,num[cnt[a]]++更新更新后cnt[a]集合的统计
		else num[cnt[a]]--,cnt[a]--,num[cnt[a]]++,n--;
		a=n-(num[1]*1+num[2]*2+num[3]*3);//正方形的边数
		if(a==0){
			printf("NO\n");
		}else if(a==4||a==5){
			if(num[2]+num[3]>=2)printf("YES\n");//寻找矩形4条边
			else printf("NO\n");
		}else if(a==6||a==7){//a中包含矩形的2条边
			if(num[2]+num[3]>=1)printf("YES\n");//寻找矩形2条边
			else printf("NO\n");
			else printf("NO\n");
		}else{//a>=8,a中包含矩形的4条边
			printf("YES\n");
		}
	}
	return 0;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!