排列数公式Pmn=n!/(n−m)!
(m在上n在下)
组合数 
#include <stdio.h>
double fact( int n );
int main(void)
{
int m, n;
double result;
scanf("%d%d", &m, &n);
if(m > 0 && n > 0 && m <= n){
result = fact(n)/fact(n-m);
printf("result = %.0f\n", result);
}
return 0;
}
double fact( int n )
{
double sum = 1;
for (int i = 1; i <= n; i++) {
sum*= i;
}
return sum;
}
冒泡与选择排序
#include <stdio.h>
int main() {
int arr[5]={3,5,4,2,9};
//冒泡 一共比较n-1趟 前一个与后一个进行比较 每次比较的数值越来越少(每次都确定最后一个值然后减去那个值 每次有i个值无需检查)
printf("冒泡\n");
int len=5;
for(int i=0;i<len-1;i++)
{
for(int j=0;j<len-i-1;j++)
{
if(arr[j]>arr[j+1])
{
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
for(int i=0;i<len;i++)
{
printf("%d ",arr[i]);
}
//选择 主要思想是交换索引 每次更新最小值的索引 然后往后遍历遇见更小的则交换
printf("\n");
printf("选择\n");
for(int i=0;i<len-1;i++)
{
int index=i;
for(int j=i+1;j<len;j++)
{
if(arr[index]>arr[j])
{
index=j;
}
}
//一旦有更小的值 记录索引 将第i个数值与后面最小的进行交换
int temp=arr[i];
arr[i]=arr[index];
arr[index]=temp;
}
for(int i=0;i<len;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
辗转相除法
#include <stdio.h>
int gcd(int a, int b)
{
return b==0?a:gcd(b,a%b);//最大公约数
}
int main() {
int a,b;
scanf("%d %d",&a,&b);
printf("%d\n",gcd(a,b));
printf("%d",a*b/gcd(a,b));//这里是最小公倍数 两数相乘除以最大公约数
return 0;
}
专项
专项2
7-2 计算物体自由下落的距离
公式s=(1/2)*g*t*t 垂直距离等于二分之一得重力*速度得平方
#include <stdio.h>
int main(void)
{
printf("height = %.2lf",0.5*10*3*3);
return 0;
}
7-4 3人分糖果
#include <stdio.h>
int main(void)
{
int a,b,c;
a=8,b=9,c=10;
a=a/3; //先把a分成三份
b=(a+9)/3; //这里b已经加上了a 然后再将b分成三份
c=(a+b+c)/3;//这里c已经加上了b和a 再次将c分成三份
//再把没加得部分加回来
a=a+b+c;
b=b+c;
printf("%d %d %d",a,b,c);
return 0;
}
方法二
7-7 计算火车运行时间
#include<stdio.h>
int main()
{
int a,b;
scanf("%d %d",&a,&b);
int ah=a/100;
int am=a%100;
int bh=b/100;
int bm=b%100;
int hh=bh-ah;
int mm=bm-am;
if(mm<0){
hh-=1;mm=60+mm;
}
printf("%02d:%02d",hh,mm);
return 0;
}
方法1 利用分钟相减的正负来判断小时的增减
#include <stdio.h>
int main(void)
{
int a,b;
scanf("%d %d",&a,&b);
int ah=a/100;int am=a%100;
int bh=b/100;int bm=b%100;
int ch=bh-ah;int cm=bm-am;
ch*=60;int csum=ch+cm;
ch=csum/60;cm=csum-ch*60;
printf("%02d:%02d",ch,cm);
return 0;
}
方法2 把小时转化成分钟统一计算
7-8 判断一个三位数是否为水仙花数
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
int a,b,c;
if(n>=100&&n<=999)
{
a=n/100; //百位
b=(n%100)/10; //十位
c=n%10; //个位
if(n==a*a*a+b*b*b+c*c*c)
{
printf("Yes");
}
else
{
printf("No");
}
}
else
{
printf("Invalid Value.");
}
return 0;
}
7-20 求简单交错序列前N项和
#include <stdio.h>
int main() {
int n;
double sum = 0.0;
int count = 0;
scanf("%d", &n);
int c = 1;
for (int i = 1; i <= n; i++) {
while (count != n) {
if (c % 2 != 0) {
sum += 1.0 / c;
} else if (c % 2 == 0) {
sum -= 1.0 / c;
}
c = c + 3;
count++;
}
}
printf("sum = %.3lf", sum);
return 0;
}
曾经的错误写法
#include <stdio.h>
int main(void)
{
double sum=1.0;
int n;scanf("%d",&n);
for (int i = 4; i <= n; i+=3)
{
if(i%2==0)
{
sum-=1.0/i;
}
else
{
sum+=1.0/i;
}
}
printf("The sum is %.3lf\n",sum);
return 0;
}
前n项和的意思是循环遍历n次 而不是整个式子的分母到n结束
7-22 求平方与倒数序列的部分
专项三
例题3-7 统计英文字母和数字字符[2]
#include <stdio.h>
int main(void)
{
int n;scanf("%d",&n);
getchar();
int letter = 0, digit = 0, other = 0;
while (n--)//n一进入循环就会先-1 变成9 但是在这个while循环中 当n==0时先会完成此次的循环 再退出循环
{
int ch;ch=getchar();
if (ch>='0' && ch<='9')
{
digit ++;
}
else if (ch>='A' && ch<='Z' || ch>='a' && ch<='z')
{
letter ++;
}
else
{
other ++;
}
}
printf("letter = %d, digit = %d, other = %d",letter,digit,other);
return 0;
}
例题3-8 查询自动售货机中商品的价格
改前代码
#include <stdio.h>
int main() {
int n;int a;int count=0;
printf("[1] crisps\n[2] popcorn\n[3] chocolate\n[4] cola\n[0] exit\n");
while(scanf("%d",&a)||count<=5)
{
if (count==5)
{
printf("Thanks");
return 0;
}
switch (a)
{
case 1:printf("price = 3.0\n");count ++;break;
case 2:printf("price = 2.5\n");count ++;break;
case 3:printf("price = 4.0\n");count ++;break;
case 4:printf("price = 3.5\n");count ++;break;
case 0:printf("Thanks\n");return 0;
default:printf("price = 0.0\n");count ++;break;
}
}
return 0;
}
改后
#include <stdio.h>
int main() {
int n;int a;int count=0;
printf("[1] crisps\n[2] popcorn\n[3] chocolate\n[4] cola\n[0] exit\n");
while(count<=5)
{ scanf("%d",&a);
if (count==5)
{
printf("Thanks");
return 0;
}
switch (a)
{
case 1:printf("price = 3.0\n");break;
case 2:printf("price = 2.5\n");break;
case 3:printf("price = 4.0\n");break;
case 4:printf("price = 3.5\n");break;
case 0:printf("Thanks\n");return 0;
default:printf("price = 0.0\n");break;
}
count ++;
}
return 0;
}
输入 判断 再计数
例题3-9 两个数的简单计算器 (scanf 和 %c)
#include <stdio.h>
int main() {
int num1, num2;
char c;
int result;
scanf("%d %c %d", &num1, &c,&num2);
switch (c) {
case '+':
result = num1 + num2;
printf("%d\n", result);
break;
case '-':
result = num1 - num2;
printf("%d\n", result);
break;
case '*':
result = num1 * num2;
printf("%d\n", result);
break;
case '/':
result = num1 / num2;
printf("%d\n", result);
break;
case '%':
result = num1 % num2;
printf("%d\n", result);
break;
default:
printf("ERROR\n");
break;
}
return 0;
}
当scanf遇到%c时 最好在%c前面加个空格 scanf("%d %c %d", &num1, &c,&num2);
这样可以防止读入前面的空格(前提是%d %c %d"中间同样也有空格)
专项四
7-3 统计数字字符和空格 如果换成scanf可不可以?
#include <stdio.h>
#include <math.h>
int main() {
char ch;int blank=0,digit=0,other=0;
while ((ch = getchar())!= '\n') //换成while (scanf("%c",&ch)!='\n') 是错误的写法具体看下面
{
switch (ch)
{
case ' ':blank++;break;
default:{ if (ch>='0'&&ch<='9')
{
digit++;
}
else
{
other++;
}}
break;
}
}
printf("blank = %d, digit = %d, other = %d",blank,digit,other);
return 0;
}
scanf
在读取字符时默认会跳过任何空白字符(包括空格、制表符和换行符),直接使用 scanf("%c", &ch)
来捕获换行符通常不会成功,因为换行符会被当作空白字符而被跳过。
遇见/n还是老老实实用getchar
7-5 找出最小值 三目比较
#include <stdio.h>
#include <limits.h>
int main() {
int n;
scanf("%d",&n);
int arr[n];int min=INT_MAX;//换成足够大的min效果一样 因为要确保min可以被正常替换
for (int i = 0; i < n; i++)
{
scanf("%d",&arr[i]);
min = min < arr[i] ? min : arr[i];//两两相比可以用三目进行比较
}
printf("min = %d",min);
return 0;
}
7-7 特殊a串数列求和
#include <stdio.h>
int main() {
int n,a;int sum=0;//sum是单个的值 需要再声明一个sum2来存储所有sum的总和
int sum1=0;
scanf("%d %d",&a,&n);
for (int i = 1; i <= n; ++i) {
sum=sum*10;
sum+=1;
sum1+=sum;
}
sum1*=a;
printf("%d",sum1);
return 0;
}
先将a看成1 aa就是11 aaa=111 以此类推
那么可以把算式拆解成(1+11+111+......)*a
(1+11+111+......)=sum1
在循环中每次求得是单个的数值 例如11=1*10+1 111=11*10+1 1111=111*10+1
每次都是前一个数值*10+1
最后把数字加到sum1中即可
7-8 猜数字游戏
#include <stdio.h>
int main(void) {
int num, N, gs;
scanf("%d %d", &num, &N);
int guess;//用户输入
while (1) {
scanf("%d", &guess);
gs++;
if ((gs > N) || guess < 0) {
printf("Game Over\n");
return 0;
}
if (guess > num) {
printf("Too big\n");
}
if (guess < num) {
printf("Too small\n");
}
if (guess == num) {
if (gs == 1) {
printf("Bingo!\n");
}
else if (gs <= 3) {
printf("Lucky You!\n");
}
else {
printf("Good Guess!\n");
}
return 0;
}
}
}
先判断大小 最后统计猜测次数
**7-9 兔子繁衍问题
#include <stdio.h>
int main()
{
int n;
scanf("%d",&n);
int a=1,b=1;
int count=2;
while (1)
{
if(n==1){printf("1");return 0;}
int c=a+b;count++;
if(c>=n)
{
printf("%d",count);
break;
}
a=b;b=c;
}
return 0;
}
**7-10 高空坠球
#include <stdio.h>
int main()
{
int n;double h;
scanf("%lf %d", &h,&n);
double sum=h;
if (n==0)
{
printf("0.0 0.0");
return 0;
}
for (int i = 1; i <= n; i++)
{
h=h/2.0;
sum+=h*2.0;
}
sum=sum-h*2;
printf("%.1lf %.1lf",sum,h);
return 0;
}
7-11 求分数序列前N项和
#include <stdio.h>
int main()
{
double fz,fm;
double sum=2.0;
int n;
scanf("%d",&n);
fz=2.0;fm=1.0;
for(int i=2;i<=n;i++)
{
double temp=fm;//因为分母要先被替换所以需要 用temp存储一下分母
fm=fz;
fz=fz+temp;
sum+=fz/fm*1.0;
}
printf("%.2lf",sum);
return 0;
}
**7-12 求e的近似值
#include <stdio.h>
double fact(int n)
{
if(n==0){return 1;}
return n*fact(n-1);
}
int main()
{
int n;double sum;