AtCoder Beginner Contest 165 E Rotation Matching 构造不同场次的间距均不相等

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 <stdio.h>
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 <stdio.h>
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)

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值