弄了几天终于做出了。
csdn 编程挑战题目如下:
问题描述:
给你n组测试数据,每组测试数据有m(0<m<=100)个正整数,求出m个数的最小公倍数。
Input:
输入n,随后有n行,每行开头输入m,m之后有m个正整数,相邻数之间用空格隔开。
Output:
每行输出一个数(该数在int范围内,同时,数前面加个“Case 1: ”,表示第几个Case,如“Case 1: 6”),相邻两组结果之间有一个空行,输出完最后一个结果后,再加一个空行,具体形式见样例。
答题说明:
输入样例:
3
2 2 3
3 2 5 7
5 1 2 3 4 5
输出样例:
Case 1: 6
Case 2: 70
Case 3: 60
初级版本:把输入的数组值设置为定值。
#include<stdio.h>
int gcd(int a ,int b)//求两个数的最大公约数
{
int temp;
if(a < b)
{
temp = a;
a = b;
b = temp;
}
while(1)
{ temp = a %b;//缓存余数
a = b ; //a 存放的是被除数,永远是待求的两个数中较大的。
if(temp == 0)
{
break;
}
b=temp;/*b存放的是上一轮的余数,作为下一轮的除数。如果这一轮余数为零,那么就不再求最大公约数。*/
}
return b;
}
void main()
{
int i,a,b,bb[2][2]= {{2,3},{4,3}}; //数组如果赋值,必须在初始化时才可以这样写。
//否则,在下面时,bb[2][2]= {{2,3},{4,3}}会报错,因为此时bb[2][2]就指定一个值。
//为了测试,初步把数组的值都定死了
int k,res,j;
a = 2;
b = 2;
for(i = 0; i < a; i++)
{
res = bb[i][0];
printf("Case %d",i);
printf(": ");
/*k不能从0开始,因为一组数除了最后一个数未参加求最大公约数时,前面得出的最大公约数和这最后一个数开始执行下面的一句时,
会导致进入循环体时 bb[i][k+1]中的k+1,使得数不存在数组值而出错。
for( k =0; k < b ;k ++)
res=(res * bb[i][k +1])/gcd(res,bb[i][k+1]);
*/
for( k = 1; k < b ;k ++)
res=(res * bb[i][k])/gcd(res,bb[i][k]);//直接在主程序中求每一列的最大公倍数。
printf("%d\n",res);
}
}
中级版本:手动输入数组的行和列。其他仍一样,求出每一行数的最小公倍数仍在主函数中处理。代码如下:
void main()
{
int i,a,b,bb[10][10],count[10];
int k,res,j,w;
w=0;
scanf("%d\n",&a);
w++;
for(i = 0; i < a; i++)
{
scanf("%d\n",&b);
w++;
count[i] = b;
for(j = 0; j < b; j++)
{
scanf("%d\n",&bb[i][j]);
w++;
}
}
//Dev-c++编译器很奇怪,当输入所以的数字完按enter不能出结果,得重新再随便按一个键,再按enter才能出结果。
//为了测试到底从键盘传入多少个数进去,故设了w这个计数器。
printf("You have already input %d",w);
printf(" numbers\n");
for(i = 0; i < a; i++)
{
res = bb[i][0];
printf("Case %d",i);
printf(": ");
/*k不能从0开始,因为一组数除了最后一个数未参加求最大公约数时,前面得出的最大公约数和这最后一个数开始执行下面的一句时,
会导致进入循环体时 bb[i][k+1]中的k+1,使得数不存在数组值而出错。
for( k =0; k < b ;k ++)
res=(res * bb[i][k +1])/gcd(res,bb[i][k+1]);
*/
for( k = 1; k < count[i] ;k++)
res=(res * bb[i][k])/gcd(res,bb[i][k]);//在主函数中间处理求每一行的最小公倍数,因为方便得知数组的长度 。
printf("%d\n",res);
}
}
为了简化主函数,抽出一些方法,采取主函数调用的方式,简洁一些。
最终的版本如下:
#include<stdio.h>
int gcd(int a ,int b)//求两个数的最大公约数
{
int temp;
if(a < b)
{
temp = a;
a = b;
b = temp;
}
while(1)
{ temp = a %b;
a =b ;
if(temp == 0)
{
break;
}
b = temp;
}
return b;
}
int lcm(int a,int b)//求两个数的最小公倍数
{
int result =a *b /gcd(a,b);
return result;
}
int rowlcm(int *b,int n) //求每一组数的最小公倍数
{
int k,res;
res = b[0];
for(k = 1 ;k < n;k++)
{
res= lcm(res,b[k]);
}
return res;
}
void main()
{
int i,j,a,b,bb[10][10],count[10];
scanf("%d\n",&a);//输入行数。代表总共有几组数据参加运算。
for(i = 0; i < a; i++)
{
scanf("%d\n",&b);//输入列数。代表每一组中总共有几个数。
count[i] = b;//数组count保存当前的列数
for(j = 0; j < b; j++)
scanf("%d\n",&bb[i][j]);
}
for(i = 0; i < a; i++)
{
printf("Case %d",i);
printf(":%d\n", rowlcm(bb[i],count[i]));//c语言中处理形参为数组时,长度不好求,直接传数组长度过去
}
}