2020牛客多校第十场I-Tournament

本文详细分析了2020年牛客多校第十场I-Tournament的解题思路,分为Case 1到Case 4进行探讨。重点解释了如何让所有人尽量一块一块地出现,以达到最优方案。作者将不同情况分开阐述,以助于理解问题本质,指出大部分AC代码将Case 12和Case 34合并可能造成理解难度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Decription

在这里插入图片描述

Solution

首先,看到这题会有一种冲动
在这里插入图片描述
怎么办!
问题在于,我们让第一个人尽快离开,其他人等了很久
我们把它拆成四部分
记住最优宗旨要让所有人尽量一块一块地出现

Case 1

1→n21 \rightarrow \cfrac{n}{2}12n个人互相比
要让所有人尽量一块一块地出现
For instance,n=10

premulationpremulationpremulation
121\qquad212
131\qquad313
232\qquad323
141\qquad414
242\qquad424
343\qquad434
151\qquad515
252\qquad525
353\qquad535
454\qquad545
//1~n/2
		for(i=2;i<=n/2;++i)
			for(j=1;j<i;++j)
				printf("%d %d\n",j,i);

Case 2

1→n21 \rightarrow \cfrac{n}{2}12n个人没开始走,前1→n21 \rightarrow \cfrac{n}{2}12n个人和后n2+1→n\cfrac{n}{2}+1 \rightarrow n2n+1n个人互相比

premulationpremulationpremulation
.........
171\qquad717
272\qquad727
373\qquad737
181\qquad818
282\qquad828
191\qquad919
//1~n/2 versus n/2+1~n	upper half	
		for(i=n/2+1;i<n;++i)
			for(j=1;j<=n-i;++j)
				printf("%d %d\n",j,i);

Case 3

1→n21 \rightarrow \cfrac{n}{2}12n个人开始依次离开,前1→n21 \rightarrow \cfrac{n}{2}12n个人和后n2+1→n\cfrac{n}{2}+1 \rightarrow n2n+1n个人互相比

premulationpremulationpremulation
1101\qquad10110
292\qquad929
2102\qquad10210
383\qquad838
393\qquad939
3103\qquad10310
474\qquad747
484\qquad848
494\qquad949
4104\qquad10410
.........
//1~n/2 versus n/2+1~n	lower half	
		for(i=1;i<=n/2;++i)
			for(j=n-i+1;j<=n;++j)
				printf("%d %d\n",i,j);

Case 4

  • 1→n21 \rightarrow \cfrac{n}{2}12n个人走光了,后n2+1→n\cfrac{n}{2}+1 \rightarrow n2n+1n个人互相比
  • 排列与Case 1类似
//n/2+1~n
		for(i=n/2+1;i<n;++i)
			for(j=i+1;j<=n;++j)
				printf("%d %d\n",i,j);

Thoughts

  • 几乎所有的ac代码都是把Case 12和Case 34合在一起,代码简洁但比较难理解
  • 我把四种情况剥离开来,能更好地理解这个问题的本质
  • 看似简单实则充满思维的题,

dlstsdy!

#include <cstdio>
int T,n,i,j;
int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		//1~n/2
		for(i=2;i<=n/2;++i)
			for(j=1;j<i;++j)
				printf("%d %d\n",j,i);
		//1~n/2 versus n/2+1~n	upper half	
		for(i=n/2+1;i<n;++i)
			for(j=1;j<=n-i;++j)
				printf("%d %d\n",j,i);
		//1~n/2 versus n/2+1~n	lower half	
		for(i=1;i<=n/2;++i)
			for(j=n-i+1;j<=n;++j)
				printf("%d %d\n",i,j);
		//n/2+1~n
		for(i=n/2+1;i<n;++i)
			for(j=i+1;j<=n;++j)
				printf("%d %d\n",i,j);					
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值