Decription
Solution
首先,看到这题会有一种冲动
怎么办!
问题在于,我们让第一个人尽快离开,其他人等了很久
我们把它拆成四部分
记住最优宗旨要让所有人尽量一块一块地出现
Case 1
前1→n21 \rightarrow \cfrac{n}{2}1→2n个人互相比
要让所有人尽量一块一块地出现
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}1→2n个人没开始走,前1→n21 \rightarrow \cfrac{n}{2}1→2n个人和后n2+1→n\cfrac{n}{2}+1 \rightarrow n2n+1→n个人互相比
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}1→2n个人开始依次离开,前1→n21 \rightarrow \cfrac{n}{2}1→2n个人和后n2+1→n\cfrac{n}{2}+1 \rightarrow n2n+1→n个人互相比
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}1→2n个人走光了,后n2+1→n\cfrac{n}{2}+1 \rightarrow n2n+1→n个人互相比
- 排列与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);
}
}