AtCoder Beginner Contest 165 比赛人数11730 比赛开始后15分钟看到所有题
AtCoder Beginner Contest 165 E Rotation Matching 构造不同场次的间距均不相等
总目录详见https://blog.csdn.net/mrcrack/article/details/104454762
在线测评地址https://atcoder.jp/contests/abc165/tasks/abc165_e
讨论间距的原因:
在N轮比赛中,不同场次,不同竞技场中,会遇到雷同字母,若有间距相等的情况,另一个字母大概率相同,造成了冲突。
故要设置不同间距。如有不明,读者继续往下看。
1.举个会冲突的例子
5 2
构造比赛如下,请注意会有冲突发生。
1 3
2 5
第1轮
当前选手A B C D E
选手数值1 2 3 4 5
数字表示0 1 2 3 4
竞技场上选手AC(02)间距2-0=2;BE(14)间距4-1=3
第2轮
当前选手A B C D E
选手数值2 3 4 5 1
数字表示0 1 2 3 4
竞技场上选手EB(41)间距1-4+5=2也可认为间距是4-1=3,此时与第一轮 BE(14)间距4-1=3 冲突;
AD(03)间距3-0=3
读者可以看到
1 3 间距可以是3-1=2,也可以是1-3+5=3
2 5 间距可以是5-2=3,也可以是2-5+5=2
可以看到1 3的间距与2 5的间距有相同的情况,故在5轮比赛中,一定会冲突。
2.需要构造的不同场次的间距均不相等,那么如何构造呢,请接着看。
2.1.1请看n=11,m=5的极端情况,请注意,m是奇数
这样构造
2 4 间距4-2=2,间距也可以是2-4+11=9
1 5 间距5-1=4,间距也可以是1-5+11=7
8 9 间距4-3=1,间距也可以是3-4+11=10
7 10 间距10-7=3,间距也可以是7-10+11=8
6 11 间距11-6=5,间距也可以是6-11+11=6
请看上面的间距,没有一处是相等的,所有不会出现冲突的情况,读者若不信,可以手工进行模拟。
2.1.2若n=11,m=3的情况
这样构造
2 4 间距4-2=2,间距也可以是2-4+11=9
1 5 间距5-1=4,间距也可以是1-5+11=7
8 9 间距4-3=1,间距也可以是3-4+11=10
请看上面的间距,没有一处是相等的,所有不会出现冲突的情况,读者若不信,可以手工进行模拟。
2.1.3请看n=12,m=5的极端情况,需删去1个点,变成下图
这样构造
2 4 间距4-2=2,间距也可以是2-4+12=10 注意计算第2个间距时是+12不是+11
1 5 间距5-1=4,间距也可以是1-5+12=8
8 9 间距4-3=1,间距也可以是3-4+12=11
7 10 间距10-7=3,间距也可以是7-10+12=9
6 11 间距11-6=5,间距也可以是6-11+12=7
请看上面的间距,没有一处是相等的,所有不会出现冲突的情况,读者若不信,可以手工进行模拟。
2.2请看n=13,m=6的极端情况,请注意,m是偶数
这样构造
3 5 间距5-3=2,间距也可以是3-5+13=11
2 6 间距6-2=4,间距也可以是2-6+13=9
1 7 间距7-1=6,间距也可以是1-7+13=7
10 11 间距11-10=1,间距也可以是10-11+13=12
9 12 间距12-9=3,间距也可以是9-12+13=10
8 13 间距13-8=5,间距也可以是8-13+13=8
请看上面的间距,没有一处是相等的,所有不会出现冲突的情况,读者若不信,可以手工进行模拟。
3.1知道原理后,怎么编码,就看个人了,提供笔者的AC参考代码如下
#include
int main(){
int n,m,i,t,l,r;
scanf("%d%d",&n,&m);
if(n%2==0)n--;//n是偶数
t=(n-1)/2;//t表示n对应的最大m值
if(t==1)return 0*printf("1 2\n");//特判
l=t/2,r=l+2;//先打印r-l为偶数的区间
for(i=1;i<=m;i++){
printf("%d %d\n",l,r);
l--,r++;
if(l==0)l=(t+n+1)/2,r=l+1;//区间跳跃,跳跃到r-l为奇数的区间
}
return 0;
}
3.2若觉得笔者上述代码太精炼,可以看下面这个冗余的AC代码。
#include
int main(){
int n,m,i,t,l,r;
scanf("%d%d",&n,&m);
if(n%2==0)n--;
t=(n-1)/2;
if(t==1)return 0*printf("1 2\n");//特判
if(t&1){//t是奇数
l=t/2,r=l+2;
for(i=1;i<=m;i++){
printf("%d %d\n",l,r);
l--,r++;
if(l==0)l=(t+n)/2,r=l+1;
}
}else{//t是偶数
l=t/2,r=l+2;
for(i=1;i<=m;i++){
printf("%d %d\n",l,r);
l--,r++;
if(l==0)l=(t+1+n)/2,r=l+1;
}
}
return 0;
}
4.前面所有的内容,都是建立在对样例理解的基础上得出的。样例模拟如下,有耐心的,可以看一下。
4 1
6种情况
1 2可行;1 4可行;2 3可行;
1 3冲突;2 4冲突;3 4可行
1.1 2可行
第1轮
当前选手A B C D
选手数值1 2 3 4
数字表示0 1 2 3
竞技场上选手AB(01)间距1-0=1
第2轮
当前选手A B C D
选手数值2 3 4 1
数字表示0 1 2 3
竞技场上选手DA(30)间距0-3+4=1
第3轮
当前选手A B C D
选手数值3 4 1 2
数字表示0 1 2 3
竞技场上选手CD(23)间距3-2=1
第4轮
当前选手A B C D
选手数值4 1 2 3
数字表示0 1 2 3
竞技场上选手BC(12)间距2-1=1
2.1 3冲突
第1轮
当前选手A B C D
选手数值1 2 3 4
数字表示0 1 2 3
竞技场上选手AC(02)间距2-0=2
第2轮
当前选手A B C D
选手数值2 3 4 1
数字表示0 1 2 3
竞技场上选手DB(31)间距1-3+4=2
第3轮
当前选手A B C D
选手数值3 4 1 2
数字表示0 1 2 3
竞技场上选手CA(20)间距0-2+4=2 与 第1轮 冲突
3.1 4可行
第1轮
当前选手A B C D
选手数值1 2 3 4
数字表示0 1 2 3
竞技场上选手AD(03)间距3-0=3
第2轮
当前选手A B C D
选手数值2 3 4 1
数字表示0 1 2 3
竞技场上选手DC(32)间距2-3+4=3
第3轮
当前选手A B C D
选手数值3 4 1 2
数字表示0 1 2 3
竞技场上选手CB(21)间距1-2+4=3
第4轮
当前选手A B C D
选手数值4 1 2 3
数字表示0 1 2 3
竞技场上选手BA(10)间距0-1+4=3
4.2 3可行
第1轮
当前选手A B C D
选手数值1 2 3 4
数字表示0 1 2 3
竞技场上选手BC(12)间距2-1=1
第2轮
当前选手A B C D
选手数值2 3 4 1
数字表示0 1 2 3
竞技场上选手AB(01)间距1-0=1
第3轮
当前选手A B C D
选手数值3 4 1 2
数字表示0 1 2 3
竞技场上选手DA(30)间距0-3+4=1
第4轮
当前选手A B C D
选手数值4 1 2 3
数字表示0 1 2 3
竞技场上选手CD(23)间距3-2=1
5.2 4冲突
第1轮
当前选手A B C D
选手数值1 2 3 4
数字表示0 1 2 3
竞技场上选手BD(13)间距3-1=2
第2轮
当前选手A B C D
选手数值2 3 4 1
数字表示0 1 2 3
竞技场上选手AC(02)间距2-0=2
第3轮
当前选手A B C D
选手数值3 4 1 2
数字表示0 1 2 3
竞技场上选手BD(31)间距1-3+4=2 与 第1轮 冲突
6.3 4可行
第1轮
当前选手A B C D
选手数值1 2 3 4
数字表示0 1 2 3
竞技场上选手CD(23)间距3-2=1
第2轮
当前选手A B C D
选手数值2 3 4 1
数字表示0 1 2 3
竞技场上选手BC(12)间距2-1=1
第3轮
当前选手A B C D
选手数值3 4 1 2
数字表示0 1 2 3
竞技场上选手AB(01)间距1-0=1
第4轮
当前选手A B C D
选手数值4 1 2 3
数字表示0 1 2 3
竞技场上选手AD(30)间距0-3+4=1
样例模拟
Input:
7 3
Output:
1 6
2 5
3 4
第1轮
当前选手A B C D E F G
选手数值1 2 3 4 5 6 7
数字表示0 1 2 3 4 5 6
竞技场上选手AF(05),BE(14),CD(23)
第2轮
当前选手A B C D E F G
选手数值2 3 4 5 6 7 1
数字表示0 1 2 3 4 5 6
竞技场上选手GE(64),AD(03),BC(12)
第3轮
当前选手A B C D E F G
选手数值3 4 5 6 7 1 2
数字表示0 1 2 3 4 5 6
竞技场上选手FD(53),GC(63),AB(01)
第4轮
当前选手A B C D E F G
选手数值4 5 6 7 1 2 3
数字表示0 1 2 3 4 5 6
竞技场上选手EC(42),FB(51),GA(60)
第5轮
当前选手A B C D E F G
选手数值5 6 7 1 2 3 4
数字表示0 1 2 3 4 5 6
竞技场上选手DB(31),EA(40),FG(56)
第6轮
当前选手A B C D E F G
选手数值6 7 1 2 3 4 5
数字表示0 1 2 3 4 5 6
竞技场上选手CA(20),DG(36),EF(45)
第7轮
当前选手A B C D E F G
选手数值7 1 2 3 4 5 6
数字表示0 1 2 3 4 5 6
竞技场上选手BG(16),CF(25),DE(36)