题解 | J-zoahhhh和小言玩游戏#

思路讲解

这里面确定数列的长度很关键,就可以解决很多人头疼的“最短”的问题
那么我们先分析问题,列出条件,拆解问题

题目条件:  
1.数列是首位相接的圈(也就是说你打印从中间哪个数字开始都可以)  
2.数列之中俩数之间是要差1的  
3.数列中比左右俩数大的数我们称之为max,比左右两边数小的我们称之为min  
4.对于输入给定的a,b,我们要使得所有max的和为a,所有min的和为b  
5.然后zoahhhh就可以获得言棍(bushi

我们不妨来假设个特殊情况,然后随便找个a来先写几个符合max和等于a的数列看看
假设a = 2吧,那么max有这么几种组合

max = 2 
max = 1,1 

那么就有这么两种数列:

0 1 2 1 0  
0 1 0 1 0 

诶,他俩是等长的欸!
假设a = 3 那么

max = 3  
max = 2,1
max = 1,1,1

数列有

0 1 2 3 2 1 0
0 1 2 1 0 1 0
0 1 0 1 0 1 0

这些也是等长的,3能拆成2和1,2能拆成俩1,而2已经得到了和用1来表达是等长的
那么根据数学归纳法再往上推,再大的数也都可以这么拆,而且无论怎么拆的,都是等长的
那么同理min也去推一下是一样的,那么我们就可以不用再纠结最短问题,直接去打印一个符合条件的数列就行了,呃,还要先计算一下长度输出,我们这个时候可以直接选择一个最简单的数列来看

那就是从min爬到max再回到min+1,把每个数的大小拉到y轴,画出来个图像就是这样的 alt

作max和min关于x轴的投影,很容易看出来总长度就是(max - min)* 2,因为就一个max和min嘛,所以也就是(a-b)* 2
而其他的数列情况也可以在这个图里面展示一下
alt

很容易看出来,其他的组合方式的数列都是和这个一样长的

代码实现

#include<stdio.h>
int main()
{
    int a,b;
    scanf("%d %d",&a,&b);
        printf("%d\n",(a-b)*2);
        for(int i=b;i<a;i++){
            printf("%d ",i);
        }
        for(int j=a;j>b;j--){
            printf("%d ",j);
        }
    return 0;
}