43 序列
43 序列
作者:
问题描述 :
明明的爸爸经常用做游戏的方法启发明明对数学的兴趣。有一次,明明爸爸准备了许多盒子和球,他要和明明做一个放球的游戏。
游戏如下:要将k个小球依次装入到若干个盒子中去(可以使用的盒子数不限)。
小球装入盒子的规则如下:
1)第一个盒子不能为空。
2)依次装入各个盒子的球数必须严格递增。例如:当k=8时,装入方法有1,2,5或1,3,4。
3)装入的盒子数尽可能多。
4)所有相邻盒子的球数之差的绝对值之和最小。
如上例中:装入法1,2,5,则差的绝对值之和为(2-1)+(5-2)=4。装入法1,3,4,则差的绝对值之和为(3-1)+(4-3)=3。因此应该采用后一种装法。
明明明白了规则以后,就兴致盎然地玩起了游戏。起先明明玩得很有劲,每次都能顺利的找出最佳的装小球的方法。但是随着小球数量的增多,装小球的方法也就变得越来越多,明明就需要花更多的时间才能找到最佳的装球方法,这使得明明有些犯难了。于是明明想到了你,他想请你帮他写一个程序,他把小球的数量告诉你,而你的程序用来计算装小球的方法。
明明的问题可以归结为:告诉你小球的数量k,然后通过程序计算出盒子装小球的最佳方法。
输入说明 :
你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据仅占一行,每行有一个整数k(1 ≤k ≤10000),即小球的个数。每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。
输出说明 :
对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将每组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果为一串整数,即表示依次放入各个盒子里的小球的个数,每两个数字之间用一个‘,’分隔。每组运算结果单独占一行,其行首和行尾都没有任何空格或其他任何字符,每组运算结果与其后一组运算结果之间没有任何空行或其他任何字符,第一组运算结果前面以及最后一组运算结果后面也都没有任何空行或其他任何字符。 注:通常,显示屏为标准输出设备。
输入范例 :
1
8
10
输出范例 :
1
1,3,4
1,2,3,4
解题思路:这道题目直接用一个数组按照增量为1进行模拟填充,但是到后来我们发现
1、填充的小球个数正好满足题目要求,输出结果即可
2、填充的小球个数超过题目要求。
对于第二种情况,我们要在超过题目要求的数量之前进行判断,特殊处理。为了间隔最小,
那么从后往前循环填充1个小球(注意0号不填充)
主要代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 #include <string.h> 5 #include <ctype.h> 6 7 #define maxn 200 8 9 int rec[maxn] = {0}; 10 int k,len = 0;//模拟栈 11 int answer(int rec[],int num); 12 void printArray(int rec[],int len); 13 int main(){ 14 15 int i,j; 16 while(scanf("%d",&k)!=EOF){ 17 len = 0; 18 //放小 球 19 answer(rec,1);//第一次放入1个,从0开始放 20 printArray(rec,len); 21 } 22 23 return 0; 24 } 25 26 int answer(int rec[],int num){ 27 int sum = 0; 28 //printf("sum=%d\n",sum); 29 while(sum<k){ 30 rec[len] = num; 31 sum = sum + num; 32 num++; 33 len++; 34 if(sum + num>k&&sum<k){ 35 //补充 36 int idx = len-1; 37 while(sum<k){ 38 rec[idx] = rec[idx]+1; 39 sum = sum +1; 40 idx--; 41 if(idx == 0){ 42 idx = len -1; 43 } 44 } 45 } 46 } 47 return 0; 48 } 49 50 void printArray(int rec[],int len){ 51 int i; 52 for(i=0;i<len;i++){ 53 printf("%d",rec[i]); 54 if(i!=len-1){ 55 printf(","); 56 } 57 } 58 printf("\n"); 59 }