程序练习题(2)

这篇博客探讨了两个计算机科学问题。首先,它介绍了奇偶序列生成算法,即从一个整数开始,根据奇偶性进行操作,直至得到1。接着,讨论了如何计算给定范围内所有整数的最大循环节长度。其次,提出了一个瓶子交换问题,涉及如何通过交换瓶子位置将乱序的瓶子重新排序。最后,介绍了一个包子铺问题,探讨在有限种类包子数量下,哪些数量无法被凑出。
摘要由CSDN通过智能技术生成


奇偶算法序列

考虑如下的序列生成算法:从整数 n 开始,如果 n 是偶数,把它除以 2;如果 n 是奇数,把它乘 3 加1。用新得到的值重复上述步骤,直到 n = 1 时停止。例如,n = 22 时该算法生成的序列是:22,11,34,17,52,26,13,40,20,10,5,16,8,4,2,1。人们猜想(没有得到证明)对于任意整数 n,该算法总能终止于 n = 1。这个猜想对于至少 1 000 000内的整数都是正确的。对于给定的 n,该序列的元素(包括 1)个数被称为 n 的循环节长度。在上述例子中,22 的循环节长度为 16。输入两个数 i 和 j,你的任务是计算 i 到 j(包含 i 和 j)之间的整数中,循环节长度的最大值。
【输入】输入每行包含两个整数 i 和 j。所有整数大于 0,小于 1000000。
【输出】对于每对整数 i 和 j,按原来的顺序输出 i 和 j,然后输出二者之间的整数中的最大循环节长度。这三个整数应该用单个空格隔开,且在同一行输出。对于读入的每一组数据,在输出中应位于单独的一行。
【输入范例】
1 10
100 200
201 210
900 1000
【输出范例】
1 10 20
100 200 125
201 210 89
900 1000 174

#include "stdio.h"
long int m = 0, c, a[4], b[4], l[4] = { 0,0,0,0 };
void main()
{
	void C();
	void P();
	C();
	C();
	C();
	C();
	P();
}
void P()
{
	for (m = 0; m <= 3; m++)
		printf("%d %d %d\n\n", a[m], b[m], l[m]);
}
void C()
{
	long int n = 1, k = 0, i, j, max = 0, o = 0;
	scanf("%d %d", &i, &j);
	printf("\n");
	if (i > 0 && j > 0 && i < 1000000 && j < 1000000)
		a[m] = i, b[m] = j;
	else
	{
		printf("超出数的范围!");
	}
	for (; o <= b[m] - a[m]; o++)
	{
		k = a[m] + o;
		for (; k != 1;)
		{
			if (k % 2 == 0)
			{
				k = k / 2;
				n++;
			}
			else
			{
				k = k * 3 + 1;
				n++;
			}
		}
		if (n > max)
		{
			max = n;
			l[m] = max;
		}
		n = 1;
	}
	m++;
}


交换瓶子

有N个瓶子,编号 1 ~ N,放在架子上。比如有5个编号瓶子:2 1 3 5 4。要求每次拿起2个瓶子,交换它们的位置。经过若干次后,使得瓶子的序号为:1 2 3 4 5。对于这么简单的情况,显然,至少需要交换2次就可以复位。如果瓶子更多呢?你可以通过编程来解决。
【输入】 输入格式为两行:第一行: 一个正整数N(N<10000), 表示瓶子的数目。第二行:N个正整数,用空格分开,表示瓶子目前的排列情况。
【输出】输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。
【输入输出范例】
例如,输入:
5
3 1 2 5 4
程序应该输出:
3
再例如,输入:
5
5 4 3 2 1
程序应该输出:
2

#include "stdio.h"
void main()
{
 int N,m,min=1,max,k,n;
 int *a,*b;
 scanf("%d",&N);
 a=(int *)malloc(sizeof(int)*N);
 b=(int *)malloc(sizeof(int)*N);
 for(m=0;m<N;m++)
 scanf("%d",&a[m]);
 for(m=1;m<=N;m++)
 for(n=0;n<N;n++)
 if(a[n]==m)
   b[m-1]=n;
 for(n=0,m=0;m<N;m++)
 {
  if(a[m]<a[b[m]])
    {
     k=a[m];
     a[m]=a[b[m]];
     a[b[m]]=k;
     n++;
     /*printf("***");bug*/
    }
 }
 /*for(m=0;m<N;m++)
 printf("%d ",a[m]);bug*/
 printf("%d",n);
 /*for(m=0;m<N;m++)
 printf("%d ",b[m]);bug*/
}


小明吃包

小明几乎每天早晨都会在一家包子铺吃早餐。他发现这家包子铺有N种蒸笼,其中第i种蒸笼恰好能放Ai个包子。每种蒸笼都有非常多笼,可以认为是无限笼。每当有顾客想买X个包子,卖包子的大叔就会迅速选出若干笼包子来,使得这若干笼中恰好一共有X个包子。比如一共有3种蒸笼,分别能放3、4和5个包子。当顾客想买11个包子时,大叔就会选2笼3个的再加1笼5个的(也可能选出1笼3个的再加2笼4个的)。当然有时包子大叔无论如何也凑不出顾客想买的数量。比如一共有3种蒸笼,分别能放4、5和6个包子。而顾客想买7个包子时,大叔就凑不出来了。小明想知道一共有多少种数目是包子大叔凑不出来的。
【输入】
第一行包含一个整数N。(1 <= N <= 100)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100)
【输出】一个整数代表答案。如果凑不出的数目有无限多个,输出INF。
【输入输出范例】
输入:
2
4
5

程序应该输出:
6
再例如,
输入:
2
4
6
程序应该输出:
INF
样例解释:
对于样例1,凑不出的数目包括:1, 2, 3, 6, 7, 11。
对于样例2,所有奇数都凑不出来,所以有无限多个。

#include "stdio.h"
#include "stdlib.h"
void main()
{
 int N,v,b=0,k,l=0,c,n=0,*a=NULL,all=0,max=0,min=1;
 scanf("%d",&N);
 a=(int *)malloc(sizeof(int)*(N+1));
 for(k=0;k<N;k++)
 {
  scanf("%d",&a[k]);
 }
 for(a[N]=0,k=0;k<N;k++)
 {
  a[N]=a[N]+a[k];
 }
 for(k=0;k<N;k++)
 if(a[k]<1||a[k]>100||N>100||N<1)
 {
  printf("输入数字超出范围!\n");
 }
 /*else
 {
 for(k=0;k<N;k++)
 all=all+a[k];
 for(k=0;k<N;k++)
 if(a[k]>max)
 max=a[k];
 for(k=0;k<N;k++)
 {
  if(a[k]%2==0&&a[k]!=1)
    b++;
    for(v=0;v<15;v++)
    for(c=0;c<N;c++)
    {
     if(v%a[c]!=0)
        n++;
        if(n==N)
        {
         l++;
         n=0;
        }
    }
 }
 }
 if(b==N)
 printf("INF\n");
 else
 printf("%d\n",l);*/
 /*else*/
  /*else
  for(k=1;k<=500;k++)
  if()
  if(k%Ai1!=0&&k%Ai2!=0&&k%(Ai1+Ai2)!=0&&(k-Ai1)%(Ai1+Ai2)!=0&&(k-Ai2)%(Ai1+Ai2)!=0&&k)
  {
   printf("%d ",k);
      l++;
  }
  printf("\n%d",l);*/
  for(k=0;k<N;k++)
  if(a[k]%2==0&&a[k]!=1)
    b++;
  if(b==N)
  printf("INF\n");
  else
  for(v=1;v<=100;v++)
  {
  min=v;
  for(k=0;k<N+1;k++)
  {
   for(;min-a[k]>0;)
    {
     min=min-a[k];
     for(c=0;c<N+1;c++)
     if(min%a[c]==0)
     {
      n--;
     }
    }
   if(min<0)
   min=min+a[k];
    /*printf("%d ",min);bug*/
    for(c=0;c<N+1;c++)
    if(min%a[c]!=0)
     {
      n++;
     }
    if(n==(N+1)*(N+1))
    l++;
    min=v;
  }
  /*printf("%d ",n);bug*/
  n=0;
  }
  if(l!=0)
  printf("%d",l);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值