程式練習題(2)

小屁孩囧發表於2020-10-31


奇偶演算法序列

考慮如下的序列生成演算法:從整數 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);
}

相關文章