kolakoski序列


输入

30 4 

2 1 3 1 

输出

2  2  1  1  3  1  2  2  2  1  3  3  1  1  2  2  1  3  3  3  1  1  1  2  1  3  3  1  1  2

也就是输入6个数字:30 4 2 1 3 1

输出:长度为30的 根据2 1 3 1构造出的kolakoski序列


kolakoski序列性质

(1)     分组后得  22   11  3  1  222  1  33  11     22  1  333  111      2  1  33  11   2

    每组由数字 (2    1  3  1)(2  1   3   1)(2    1    3      1)(2  1   3    1) 2组成

    可以看出每组都是由 2131   2131  2131  循环

(2) 分组后得       22   11  3  1  222  1  33  11     22  1  333  111      2  1  33  11   2

每组的长度为       2 2 113 1 2 2 2 1 3 3 1 1 2 2 1

这个长度构成的数组 和   原来的数组  相同


构造方法

找到 2 1 3 1 这个baseArray中的最大值,也就是3

构造一个30*3=90的数组midArray,这个数组有90个格子,3个一组,共30组

1.

先将90个格子全部填0

2.

然后构造这个midArray

3.

最后将midArray中的非0的数拷贝到finalArray(长度为30)


如何构造midArray使其满足kolakoski序列应有的性质?


2.1

首先填第0组(midArray[0] midArray[1] midArray[2])

midArray[0]=2  midArray[1]=2   midArray[2]=0

第0组第1组第2组第3组第4组第5组第6组第7组第26组第27组第28组第29组
21312131。。。2131
000000000000000000000000000000000000000
性质(1)数字只能为2或0数字只能为1或0数字只能为3或1数字只能为1或0
性质(2),所以两个2
220

2.2

接下来开始循环构造后面每组的数据,由于每组中数字,要么是0,要么是绿色数字,所以我们只需要确定绿色数字个数

第0组第1组第2组第3组第4组第5组第6组第7组第26组第27组第28组第29组
21312131。。。2131
000000000000000000000000000000000000000
数字只能为2或0数字只能为1或0数字只能为3或1数字只能为1或0
两个21有几个?
220110


2.3

第0组第1组第2组第3组第4组第5组第6组第7组第26组第27组第28组第29组
21312131。。。2131
000000000000000000000000000000000000000
数字只能为2或0数字只能为1或0数字只能为3或1数字只能为1或0
两个21有几个?两个3有几个?  
220110300

            

2.4

第0组第1组第2组第3组第4组第5组第6组第7组第26组第27组第28组第29组
21312131。。。2131
000000000 000000000000000000000000000000
数字只能为2或0数字只能为1或0数字只能为3或1 数字只能为1或0 
两个21有几个?两个3有几个?一个1有几个? 
220110300100

2.5

第0组第1组第2组第3组第4组第5组第6组第7组第26组第27组第28组第29组
21312131。。。2131
000000000000000000000000000000000000000
数字只能为2或0数字只能为1或0数字只能为3或1数字只能为1或0数字只能为2或0
两个21有几个?两个3有几个?一个1有几个?一个2有几个?
220110300100222

就这样一直循环下去,当填了30个非0的数字的时候,midArray构造完成(此时不一定30组都填完)


3.

最后将midArray中的 非0数  拷贝到finalArray中。


代码


import java.util.Scanner;

public class Main
{
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext())
        {
            // 最终答案的数组及 长度 30
            int finalLength = sc.nextInt();
            int[] finalArray = new int[finalLength];


            // 基础数组的长度
            int baseLength = sc.nextInt();


            // 基础数 组成的数组 2 1 3 1
            int[] baseArray = new int[baseLength];
            for (int i = 0; i < baseLength; i++)
            {
                baseArray[i] = sc.nextInt();
                System.out.print(baseArray[i] + "  ");// 2 1 3 1
            }


            // 基础数组中的最大值
            int maxOfArray = findMax(baseArray);// 3
            int midLength = maxOfArray * finalLength;// 3*30=90
            System.out.println("midLength " + midLength);


            // 中间数组 全部初始化为0, 3个一组 按组赋值
            int[] midArray = new int[midLength];
            for (int j = 0; j < midLength; j++)
            {
                midArray[j] = 0;
            }


            // 把最开始的填好 2 2
            for (int k = 0; k < baseArray[0]; k++)
            {
                midArray[k] = baseArray[0];
            }

            int baseIndex = 1;// 第几组

            int sum = midArray[0];//midArray中填了多少个非0的数

            for (int amountIndex = 1; amountIndex < midLength && sum < finalLength; amountIndex++)
            {
              //while结束 一定找到了一个非0的数的下标
                while (midArray[amountIndex] == 0)
                {
                    amountIndex++;
                }
                
                //midArray[amountIndex] 的值,就是那组数中的数字的个数
                sum += midArray[amountIndex];


                //本循环  一定填完一组数
                int start = baseIndex * maxOfArray;//每组的起始位置开始填 3 6 9 12 ...
                for (int j = 0; j < midArray[amountIndex]; j++)
                {
                    midArray[start] = baseArray[baseIndex % baseLength];
                    start++;
                }
                baseIndex++;
            }


            int x = 0;
            for (int i = 0; i < finalLength; i++)
            {
                while (midArray[x] == 0)
                {
                    x++;
                }
                finalArray[i] = midArray[x];
                x++;
            }


            System.out.println("finalAray :\n");
            for (int p = 0; p < finalLength; p++)
            {
                System.out.print(finalArray[p] + "  ");
            }


        }
    }


    public static int findMax(int[] orgArray)
    {
        int max = 0;
        for (int i = 0; i < orgArray.length; i++)
        {
            if (orgArray[i] > max)
            {
                max = orgArray[i];
            }
        }
        return max;
    }


}












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值