c语言典型问题处理方法小结
- 循环问题
(1)、数论问题
1、求素数
for(i=2;i<=a;i++)
if(a%i==0)
break;
if (a==i)
printf("yes\n");
else
|
printf("no\n");
素数概念:
对于某个整数a>1,如果它仅有平凡约数1和a,则我们称a为素数(或质数)。
整数 1 被称为基数,它既不是质数也不是合数。
整数 0 和所有负整数既不是素数,也不是合数。
2、求最大公约数和最小公倍数
a、
if(a>b)
{
t=a;
a=b;
b=t;
}
for(i=a;i>=1;i--)
if(a%i==0&&b%i==0)
break;
printf("largest common divisor:%d\n",i);
printf("least common multiple:%d\n",(a*b)/is);
b、辗转相除法求解
a1=a;
b1=b;
while(a%b!=0)
{
t=a%b;
a=b;
b=t;
}
printf("largest common divisor:%d\nleast common multiple:%d",b,a1*b1/b);
3、求完数
一个数如果恰好等于它的因子之和,这个数就称为“完数”。
例如:6的因子为1、2、3,而6=1+2+3,因此6是“完数”。
for(a=1;a<=1000;a++)
{
s=0;
for(i=1;i<=a;i++)
if (a%i==0)
{
s+=i;
if(s>=a)
break;
}
if(s==a)
printf("%d\t",a);
|
}
4、分解质因数
将一个整数写成几个质因数的连乘积,如: 输入36,则程序输出36=2*2*3*3 。
解一、
|
main()
{
int a,z,i;
clrscr();
scanf("%d",&a);
|
loop: for(z=2;z<=a;z++)
{
|
for(i=2;i<=z;i++)
if(z%i==0)
break;
|
if(z==i)
if(a%z==0)
{
k++;
if(k==1)
printf("%d=%d",a1,z);
|
else
printf("*%d",z);
a/=z;
goto loop;
}
}
}
解二:
main()
{ int n, k=2, isfirst=1;
printf("Input n="); scanf("%d",&n);
while(k<=n)
if(n%k==0)
{ if(isfirst) { printf("%d=%d", n, k); isfirst=0; }
else printf("*%d",k);
n/=k;
}
else k++;
printf("\n");
}
5、从键盘输入两个整数,输出这两个整数的商的小数点后所有1000位整数
for(i=1;i<=1000;i++)
{
t=a%b;
|
printf("%d",t*10/b);
a=t*10;
}
printf("\n");
6、编程计算并输出两个带分数的差。带分数就是由一个整数和一个真分数合成的数,两个带分数(整数、分子、分母均大于0)从键盘输入,且带分数1大于带分数2,输入格式为:整数1[分子1/分母1],整数2[分子2/分母2]。差要求化简,整个输出样式为(如差为整数,则无分数部分,如差的整数为0,则无整数部分):
整数1[分子1/分母1]-整数2[分子2/分母2]=整数[分子/分母]
例如:输入:12[6/35],8[3/5]
输出:12[6/35]-8[3/5]=3[4/7]
又如:输入:6[2/3],4[12/18]
输出:6[2/3]-4[12/18]=2
又如:输入:9[7/8],9[3/8]
输出:9[7/8]-9[3/8]=[1/2]
main()
{
int z1,fz1,fm1,fz1x,z2,fz2,fm2,fz2x,z,fz,fm,fzx,i;
scanf("%d[%d/%d],%d[%d/%d]",&z1,&fz1,&fm1,&z2,&fz2,&fm2);
fz1x=z1*fm1+fz1;
fz2x=z2*fm2+fz2;
fm=fm1*fm2;
fz=fz1x*fm2-fz2x*fm1;
for(i=fm;i>=2;i--)
if(fm%i==0&&fz%i==0)
{
fz/=i;
fm/=i;
}
z=fz/fm;
fzx=fz%fm;
if(fzx==0)
printf("%d[%d/%d]-%d[%d/%d]=%d\n",z1,fz1,fm1,z2,fz2,fm2,z);
else if(z==0)
printf("%d[%d/%d]-%d[%d/%d]=[%d/%d]\n",z1,fz1,fm1,z2,fz2,fm2,fzx,fm);
else
printf("%d[%d/%d]-%d[%d/%d]=%d[%d/%d]\n",z1,fz1,fm1,z2,fz2,fm2,z,fzx,fm);
}
(2)近似问题
1、书P122习题4-6
|
#include "math.h"
main()
{
float x,j=1,k,s,so;
int n;
scanf("%f",&x);
s=x;
so=x+1;
for(n=1;fabs(s-so)>1e-6;n++)
{
for(k=1;k<=n;k++)
j*=k;
so=s;
if(n%2!=0)
s-=x*x*x/((2*n-1)*j);
else
s+=x*x*x/((2*n-1)*j);
}
printf("%f\n",s);
2、解方程问题:
编程用二分法求解方程x3+4x2-10=0的解。
#include "math.h"
main()
{
|
float x,x1=1,x2=4,f1=-1,f;
/*f1=x1*x1*x1+4*x1*x1-10;*/
while(fabs(x2-x1)>1e-6)
{
x=(x1+x2)/2;
f=x*x*x+4*x*x-10;
|
if(f>0)
x2=x;
else
x1=x;
}
printf("%f\n",x);
}
(3)枚举法
(4)数列问题
二、数组问题
(1)排序问题
1、从小到大排序
main()
{
int a[10],i,j,t;
for(i=0;i<10;i++)
scanf("%d",&a[i]);
for(i=1;i<10;i++)
for(j=0;j<10-i;j++)
if(a[j]>a[j+1])
{
t=a[j+1];
a[j+1]=a[j];
a[j]=t;
}
for(i=0;i<10;i++)
printf("%d ",a[i]);
printf("\n");
|
}
2、从大到小排序
main()
|
{
int a[10],i,j,t;
for(i=0;i<10;i++)
scanf("%d",&a[i]);
for(i=1;i<10;i++)
for(j=9;j>=i;j--)
if(a[j]>a[j-1])
{
t=a[j-1];
a[j-1]=a[j];
a[j]=t;
}
for(i=0;i<10;i++)
printf("%d ",a[i]);
}
(2)二维数组
三、字符或字符串输入输出问题
(1)字符打印
1、打印*
此类题的溯源为书P122 4.11(1),其他题都是它的拓展
|
a、
*
**
***
****
解题要点:
此类题关键在于找到每行要打印的个数和行数的关系。此题j==i
|
b、
****
***
**
*
|
c、
*
**
***
****
解题要点:
在出现空格的时候,在找到每行要打印的‘*’个数和行数的关系后,还应找到空格和行数的关系,分不同的参数进行循环。此题k==i j==n-i
|
d、
****
***
|
**
*
e、
*
***
*****
*******
| |||
| |||
*
***
*****
*******
*****
***
*
2、打印9*9乘法表
解题要点:注意寻找行与列的规律。
i*j
i代表列
j代表行
|
3、九九乘法表
1 2 3 4 5 6 7 8 9
2 4 6 8 10 12 14 16 18
3 6 9 12 15 18 21 24 27
…
…
9 18 27 36 45 54 63 72 81
4、杨晖三角形
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
(2)字符串打印问题
|
|
1、
| ||||
| ||||
|
2、输入一字符串小写换大写
|
3、逆序输出
| |||
| |||
for(int i=n;i>=0;i--) 蓝色部分可以简写为绿色部分
cout<<a[i-1];
4、如输入:ab1 @3,;z
输出:ab1
|
@3,;z
gets(a);
while(a[0]==' ')
for(i=0;a[i]!='\0';i++)
a[i]=a[i+1];
for(i=0;a[i]!='\0';i++)
if(a[i]==' '&&a[i+1]!=' ')
printf("\n");
else if(a[i]==' '&&a[i+1]==' ')
{
for(k=i;a[k]!='\0';k++)
a[k+1]=a[k+2];
i--;
}
else
printf("%c",a[i]);
5、输入3个字符串,按从小到大排序输出这3个字符串。 使用一个两维数组贮存多个字符串
char a[81][81];
|
int i,j;
for(i=0;i<3;i++)
gets(a[i]);
for(i=0;i<3;i++)
puts(a[i]);
|
6、输入一个整数n和一个字符串str,计算并输出n进制数str的值。
如输入:7 16
则输出:13 (16)7=(13)10
如输入:16 3A
则输出:58 (3A)16=(58)10
#include "stdio.h"
#include "math.h"
main()
{
char str[81];
int n,i,s=0,t;
clrscr();
scanf("%d%s",&n,str);
for(i=0;str[i]!='\0';i++)
if(str[i]<='Z'&&str[i]>='A')
str[i]=str[i]-'A'+10;
else
str[i]=str[i]-'0';
t=strlen(str);
for(i=0;str[i]!='\0';i++)
s+=str[t-i-1]*pow(n,i);
printf("%d",s);
}
编写程序,将一个十进制正整数转换成十六进制数。
注意类比
#include <stdio.h>
main()
{
char a[20];
int x,i=0,j;
clrscr();
scanf("%d",&x);
while(x)
{
if(x%16>=10&&x%16<=15)
a[i]=x%16-10+'A';
else
a[i]=x%16+'0';
x=x/16;
i++;
}
for(j=i-1;j>=0;j--)
printf("%c",a[j]);
printf("\n");
}
7、输入一个字符串,将其中的缩写形式展开,并输出展开后的该字符串。所谓展开缩写形式就是将其中由大小写字母或数字构成的形如"a-f"、"U-Z"、"3-8" 的形式展开成为 "abcdef" 、"UVWXYZ" 、"345678",若出现"f-a"、"A-7"、"9-5"等形式则不予理睬。例如:
输入:qwe246e-hA-d$-%4-7A-Dz-xp-R4-0
输出:qwr246efghA-d$-%4567ABCDz-xp-R4-0
main()
{
char a[81];
int i,c,s,k,t;
gets(a);
for(i=0;a[i]!='\0';i++)
if(a[i]=='-') if(a[i-1]<a[i+1]&&(a[i-1]>='A'&&a[i+1]<='Z'||a[i-1]>='a'&&a[i+1]<='z'||a[i-1]>='0'&&a[i+1]<='9'))
|
{
s=strlen(a);
c=a[i+1]-a[i-1];
t=i+c-2;
for(k=s-1;k>i;k--)
a[k+c-2]=a[k];
a[s-1+c-2+1]='\0';
for(;i<=t;i++)
a[i]=a[i-1]+1;
}
puts(a);
}
补充:
循环:
求:a+aa+aaa+…..的值
#include<iostream.h>
void main()
{
int a,n,i=1,sn=0,tn=0;
cout<<"input a and n"<<endl;
cin>>a>>n;
while(i<=n)
{
tn=tn+a;
sn+=tn;
a*=10;i++;
}
cout<<"the answer is "<<sn<<endl;
}
两个乒乓球队进行比赛,各出3人。甲队为A,B,C;已对是X,Y,Z;已经抽签决定比赛名单。有人向队员大厅比赛的名单。A说他不和X比,C说他不和X,Z比。请编程序找出3对赛手的名单。
#include<iostream.h>
void main()
{
char i,j,k;
for(i='X';i<='Z';i++)
for(j='X';j<='Z';j++)
if(i!=j)
for (k='X';k<='Z';k++)
if(i!=k&&j!=k)
if(i!='X'&&k!='X'&&k!='Z')
cout<<"A--"<<i<<" B--"<<j<<" C--"<<k<<endl;
}
枚举
口袋中有红,黄,蓝,白,黑5种颜色的球若干。每次从口袋中任意取出3歌,问得到3种不同颜色球的可能取法,输出每种排列的情况。
#include<iostream.h>
#include<iomanip.h> //在C语言中不用加这句
void main()
{enum color{red ,yellow ,blue,white, black};
color pri;
int i,j,k,n=0,loop;
for(i=red;i<=black;i++)
for(j=red;j<=black;j++)
if(i!=j)
{
for (k=red;k<=black;k++)
if((k!=i)&&(k!=j))
{
n++;
cout<<setw(3)<<n; //setw是输出格式的限定
for(loop=1;loop<=3;loop++)
{
switch(loop)
{
case 1:pri=color(i);break;
case 2:pri=color(j);break;
case 3:pri=color(k);break;
default:break;
}
switch(pri)
{
case red:cout<<setw(8)<<"red";break;
case yellow:cout<<setw(8)<<"yellow";break;
case blue:cout<<setw(8)<<"blue";break;
case white:cout<<setw(8)<<"white";break;
case black:cout<<setw(8)<<"black";break;
default:break;
}
}
cout<<endl;
}
}
cout<<"total:"<<n<<endl;
}
数组:
不用strcat函数,编写程序,将两个字符串串接起来。
#include<iostream>
using namespace std;
void main()
{
int i=0;
char a[20],b[10];
gets(a);gets(b);
for(i=0;i<10;i++)
if(a[i]=='\0')break;
for(int j=0;j<10;j++)
{a[i]=b[j];i++;if(b[j]=='\0')break;}
cout<<a<<endl;
}
输入一行字符,统计其中有多少个单词,单词之间用空格分开。
#include<iostream>
using namespace std;
void main()
{
char string[100];
int i,num=0,word=0;
char c;
gets(string);
for(i=0;(c=string[i])!='\0';i++)
if(c==' ')word=0;
else if(word==0)
{word=1;num++;}
cout<<"There are "<<num<<" words"<<endl;
}
给出年,月,日,计算该日是该年的第几天
#include<iostream>
using namespace std;
void main()
{
int sum_day(int,int); //函数声明
int leap(int year); //函数声明
int year,month,day,days;
cout<<"input date"<<endl;
cin>>year>>month>>day;
cout<<year<<"/"<<month<<"/"<<day;
days=sum_day(month,day);
if(leap(year)&&month>=3)days++; //若是闰年,且在3月以后,则加一天
cout<<"is the "<<days<<" th day in this year"<<endl;
}
int sum_day(int month,int day)
{
int i;
int day_tab[12]={31,28,31,30,31,30,31,31,30,31,30,31};
for(i=0;i<month-1;i++)
day+=day_tab[i];
return(day);
}
int leap(int year)
{
int leap;
leap=year%4==0&&year%100!=0||year%400==0;
return(leap);
}
(这道题虽然用了你们不考的函数调用,但是相信你还是看的懂的,这道题主要是体现了知识的综合运用)
杨辉三角(不做了,相信你会的吧)
求3*4矩阵中的最大最小元素(用循环,也不难)
输入一个矩阵的各个元素,求转置矩阵(用循环进行赋值,然后再定义个矩阵,然后进行赋值,例如:若a矩阵为2*3,则for(i=0;i<=1;i++)
for(j=0;j<=2;j++)
b[j][i]=a[i][j];)
输出魔方阵,就是每一行每一列和对角线数字之和相等。(方阵阶数由终端输入,但只需是奇数即可)
#include<iostream.h>
#include<iomanip.h>
void main()
{
int a[16][16],i,j,k,p=1,n;
while(p==1)
{
cout<<"enter n(from 1 to 15)";
cin>>n;
if((n!=0)&&(n<=15)&&(n%2!=0))p=0;
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
a[i][j]=0;
j=n/2+1;
a[1][j]=1;
for(k=2;k<=n*n;k++)
{
i--;j++;
if(i<1&&j>n)
{i=i+2;j--;}
else
{if(i<1)i=n;if(j>n)j=1;}
if(a[i][j]==0)
a[i][j]=k;
else
{i=i+2;j--;a[i][j]=k;}
}
for(i=1;i<=n;i++)
{for(j=1;j<=n;j++)
cout<<setw(5)<<a[i][j];
cout<<endl;
}
}(这道题目当时觉得很有难度,刚刚看到时没有思路)