输入
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组 | |
2 | 1 | 3 | 1 | 2 | 1 | 3 | 1 | 。。。 | 2 | 1 | 3 | 1 |
000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 |
性质(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组 | |
2 | 1 | 3 | 1 | 2 | 1 | 3 | 1 | 。。。 | 2 | 1 | 3 | 1 |
000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 |
数字只能为2或0 | 数字只能为1或0 | 数字只能为3或1 | 数字只能为1或0 | |||||||||
两个2 | 1有几个?两个 | |||||||||||
220 | 110 |
2.3
第0组 | 第1组 | 第2组 | 第3组 | 第4组 | 第5组 | 第6组 | 第7组 | 第26组 | 第27组 | 第28组 | 第29组 | |
2 | 1 | 3 | 1 | 2 | 1 | 3 | 1 | 。。。 | 2 | 1 | 3 | 1 |
000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 |
数字只能为2或0 | 数字只能为1或0 | 数字只能为3或1 | 数字只能为1或0 | |||||||||
两个2 | 1有几个?两个 | 3有几个?一个 | ||||||||||
220 | 110 | 300 |
2.4
第0组 | 第1组 | 第2组 | 第3组 | 第4组 | 第5组 | 第6组 | 第7组 | 第26组 | 第27组 | 第28组 | 第29组 | |
2 | 1 | 3 | 1 | 2 | 1 | 3 | 1 | 。。。 | 2 | 1 | 3 | 1 |
000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 |
数字只能为2或0 | 数字只能为1或0 | 数字只能为3或1 | 数字只能为1或0 | |||||||||
两个2 | 1有几个?两个 | 3有几个?一个 | 1有几个?一个 | |||||||||
220 | 110 | 300 | 100 |
2.5
第0组 | 第1组 | 第2组 | 第3组 | 第4组 | 第5组 | 第6组 | 第7组 | 第26组 | 第27组 | 第28组 | 第29组 | |
2 | 1 | 3 | 1 | 2 | 1 | 3 | 1 | 。。。 | 2 | 1 | 3 | 1 |
000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 | 000 |
数字只能为2或0 | 数字只能为1或0 | 数字只能为3或1 | 数字只能为1或0 | 数字只能为2或0 | ||||||||
两个2 | 1有几个?两个 | 3有几个?一个 | 1有几个?一个 | 2有几个?三个 | ||||||||
220 | 110 | 300 | 100 | 222 |
就这样一直循环下去,当填了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;
}
}