[转贴]C语言复习笔记-17种小算法-解决实际问题

判断日期为一年中的第几天(考虑闰年)

复制代码
 1 /*
 2 * 计算该日在本年中是第几天,注意闰年问题
 3 * 以3月5日为例,应该先把前两个月的加起来,然后再加上5天即本年的第几天
 4 * 特殊情况,闰年且输入月份大于3时需考虑多加一天
 5 */
 6 
 7 /*
 8 *@author: 成鹏致远 
 9 *@net: http://infodown.tap.cn
10 */
11 
12 #include <stdio.h>
13 #include <stdbool.h>
14 
15 struct year_mon_day
16 {
17     int year;
18     int mon;
19     int day;
20 };
21 
22 int main()
23 {
24     int i;
25     int sum;//总天数
26     bool flag = false;//闰年标志
27     struct year_mon_day ymd;
28     
29     printf("Pls input year,mon day:");
30     scanf("%d%d%d",&ymd.year,&ymd.mon,&ymd.day);
31     
32     switch(ymd.mon)
33     {
34         case 1:
35             sum = 0;
36             break;
37         case 2:
38             sum = 31;
39             break;
40         case 3:
41             sum = 59;
42             break;
43         case 4:
44             sum = 90;
45             break;
46         case 5:
47             sum = 120;
48             break;
49         case 6:
50             sum = 151;
51             break;
52         case 7:
53             sum = 181;
54             break;
55         case 8:
56             sum = 212;
57             break;
58         case 9:
59             sum = 243;
60             break;
61         case 10:
62             sum = 173;
63             break;
64         case 11:
65             sum = 304;
66             break;
67         case 12:
68             sum = 334;
69             break;
70         default:
71             printf("data error \n");
72             return 1;
73     }
74     sum += ymd.day;
75 
76     if(ymd.year/100 || (ymd.year%4 && ymd.year%100 != 0))
77     {
78         flag = true;
79     }
80     
81     if(1==flag && ymd.mon>2)
82     {
83         sum++;
84     }
85 
86     printf("%d年%d月%d日 是%d年的第%d天 \n",ymd.year,ymd.mon,ymd.day,ymd.year,sum);
87 
88     return 0;
89 }
复制代码

十进制转十六进制

复制代码
 1 /*函数实现输入一个十进制数,输出对应的十六进制数*/
 2 /*
 3 *@author: 成鹏致远 
 4 *@net: http://infodown.tap.cn
 5 */
 6 
 7 #include <stdio.h>
 8 #include <stdbool.h>
 9 #define LIM 32
10 
11 int main(void)
12 {
13     int decimal;
14     bool negative = false;
15     printf("pls input the integer to convert:\n");
16 
17     if(!scanf("%d", &decimal))
18     {
19         printf("we need an integer, Bye-bye!\n");
20         return -1;
21     }
22     if(decimal < 0)
23     {
24         negative = true; 
25         decimal *= -1;
26     }
27 
28     int i, num[LIM];
29     for(i=0; i<LIM && decimal!=0; i++)
30     {
31         num[i] = decimal%16;
32         decimal /= 16;
33     }
34 
35     int j;
36     if(negative)
37         printf("answer: -0x");
38     else
39         printf("answer: 0x");
40 
41     for(j=i; j>0; j--){
42         switch(num[j-1]){
43             case 10:
44                 printf("a");
45                 break;
46             case 11:
47                 printf("b");
48                 break;
49             case 12:
50                 printf("c");
51                 break;
52             case 13:
53                 printf("d");
54                 break;
55             case 14:
56                 printf("e");
57                 break;
58             case 15:
59                 printf("f");
60                 break;
61             default:
62                 printf("%d", num[j-1]);
63                 break;
64         } //switch
65     } //for
66     printf("\n");
67 
68     return 0;
69 }
复制代码

打印指定的字母金字塔(技巧)

复制代码
 1 /*
 2 *    产生一个字母金字塔图案
 3 *    author:成鹏致远
 4 *    net:infodown.tap.cn
 5 */
 6 
 7 #include <stdio.h>
 8 
 9 void PintLetterPic(char);    //打印出金字搭字母图案
10 
11 int main()
12 {
13     char letter;
14 
15     printf("Please input a capital letter:");
16     scanf("%c",&letter);
17     
18     PintLetterPic(letter);
19 
20     return 0;
21 }
22 
23 void PintLetterPic(char c)    //打印出金字搭字母图案
24 {
25     int len = c - 'A'+1;    //注意这里需要+1!!!
26     int len2 = 2*len;
27     char tem[100][200];
28     int i,j;
29     char tempchar = 'A';
30 
31     for(i=0; i<100; i++)    //初始化二维数组
32     {
33         for(j=0; j<200; j++)
34         {
35             tem[i][j] = ' ';
36         }
37     }
38 /*******************************核心算法*********************************************/    
39 
40     for(i=0; tempchar<=c; i++,tempchar++)//从最中间列从上往下控制行
41     {
42         int m = 1;
43         char temp = tempchar;    //需要保存tempchar的一个临时变量,保证tempchar在while循环中不被改变
44         tem[i][len] = tempchar;    //控制最中间的一列
45 
46 
47         while('A' != temp)    //从行最中间左右控制列
48         {
49             tem[i][len-m]=tem[i][len+m]=--temp;
50             m++;
51         }
52     }
53 
54 /*******************************核心算法*********************************************/    
55 
56 
57     for(i=0; i<len; i++)    //打印出金字塔图案
58     {
59         for(j=0; j<len2; j++)
60         {
61             printf("%c",tem[i][j]);
62         }
63         printf("\n");
64     }
65 }
复制代码

求float型数的幂

复制代码
 1 /*用循环的方法实现,返回一个float 类型数的某个整数次幂,保留六位小数*/
 2 /*
 3 *@author: 成鹏致远 
 4 *@net: http://infodown.tap.cn
 5 */
 6 
 7 #include <stdio.h>
 8 #include <math.h>
 9 
10 float my_power(float cardinal, int pow);    //返回cardinal的pow次幂
11 
12 int main()
13 {
14     float cardinal;    //底数
15     int pow;    //
16 
17     printf("Please input a float cardinal and a int pow(3.14,-2):");
18     scanf("%f,%d",&cardinal,&pow);
19 
20     printf("%f的%d次幂是:%.6f \n",cardinal,pow,my_power(cardinal,pow));
21 
22     return 0;
23 }
24 
25 float my_power(float cardinal, int pow)
26 {
27     float result = 1.0;
28     int abs_pow = abs(pow);
29 
30     if(0 != abs_pow)    //非0次幂
31     {
32         while(abs_pow--)
33         {
34             result *= pow>0?cardinal:1/cardinal;
35         }    
36     }
37     else    //0次幂
38     {
39         result =1;
40     }
41     return result;
42 }
复制代码

输出小于指定数的所有素数

复制代码
 1 /*
 2 *    接受一个整数输入,然后显示所有小于或等于该数的素数
 3 *    编译时请加 -lm 选项,链接到 math 库
 4 *    author:成鹏致远
 5 *    net:infodown.tap.cn
 6 */
 7 
 8 #include <stdio.h>
 9 #include <stdbool.h>
10 #include <math.h>
11 
12 bool IsPrime(int a);//判断是否为素数
13 void PoutPrime(int a);//输出所有小于或等于该数的素数
14 
15 int main()
16 {
17     int nem;
18 
19     printf("Please input a number:");
20     scanf("%d",&nem);
21 
22     PoutPrime(nem);
23 
24     return 0;
25 }
26 
27 bool IsPrime(int a)//判断是否为素数
28 {
29     int i;
30     int j = sqrt(a);
31 
32     for(i=2; i<=j; i++)
33     {
34         if(0 == a % i)
35         {
36             return false;
37         }
38     }
39     return true;
40 }
41 
42 void PoutPrime(int a)//输出所有小于或等于该数的素数
43 {
44     printf("小于或等于%d 的所有素数列表:\t",a);
45     while(a)
46     {
47         if(IsPrime(a))
48         {
49             printf("%d\t",a);
50         }
51         a--;
52     }
53     printf("\n");
54 }
复制代码

辗转相除法求最大公约数(铺砖)

复制代码
 1 /*
 2 * 返回两个整数的最大公约数,用辗转相除法求最大公约数
 3 * 辗转相除法:铺地砖
 4 * author:成鹏致远
 5 * net:infodown.tap.cn
 6 */
 7 
 8 #include <stdio.h>
 9 
10 int Divisor(int a, int b)    //最大公约数
11 {
12     int temp;
13 
14     if(a < b)
15     {
16         a = a ^ b;
17         b = a ^ b;
18         a = a ^ b;
19     }
20     while(0 != b)
21     {
22         temp = a % b;
23         a = b;
24         b = temp;
25     }
26     return a;    //最大公约数
27                 //最大公倍数为两数的乘积除以最大公约数
28 }
29 
30 int main()
31 {
32     int a,b;
33 
34     printf("Please input two numbers:");
35     scanf("%d%d",&a,&b);
36 
37     printf("%d 和%d 的最大公约数是%d \n",a,b,Divisor(a,b));
38 }
复制代码

递归实现汉诺塔(递归思想)

复制代码
 1 /*
 2 * 递归实现汉诺塔
 3 * @author:成鹏致远
 4 * @net:infodown.tap.cn
 5 */
 6 
 7 #include <stdio.h>
 8 
 9 void move(char a, char b)//实现汉诺塔的移动
10 {
11     printf("%c—>%c \n",a,b);
12 }
13 
14 
15 /*
16 * 功 能: 递归实现汉诺塔
17 * n    : 盘子个数
18 * a,b,c: 三个盘座
19 */
20 void han_tower(int n, char a, char b, char c)
21 {
22     if(1==n)
23     {
24         move(a,c);
25     }
26     else
27     {
28         //将前n-1个盘子从a借助c移动到b
29         han_tower(n-1,a,c,b);
30         //将a上的第n个盘子移动到c
31         move(a,c);
32         //将剩下的n-1个盘子从b借助a移动到c
33         han_tower(n-1,b,a,c);
34     }
35 }
36 
37 int main()
38 {
39     int num;
40 
41     printf("Pls input the number of diskes:");
42     scanf("%d",&num);
43     printf("the step to moving %d diskes: \n",num);
44     han_tower(num,'A','B','C');
45 
46     return 0;
47 }
复制代码

乒乓球比赛对手配对(匹配)

复制代码
 1 /*
 2 题目:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定
 3     比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出
 4     三队赛手的名单。 
 5 */
 6 
 7 /*
 8 *  @author: 成鹏致远 
 9 *  @net: http://infodown.tap.cn
10 */
11 
12 #include <stdio.h>
13 
14 int main(void)
15 {
16     char i,j,k;
17     for(i='x';i<='z';i++)//a对手
18     {
19         for(j='x';j<='z';j++)//b对手
20         {
21             if(i!=j)//a,b同对
22             {
23                 for(k='x';k<='z';k++)//c对手
24                 { 
25                     if(i!=k&&j!=k)//a,b,c同对
26                     { 
27                         if(i!='x' && k!='x' && k!='z')//a不和x比,c不和x,z比
28                             printf("order is a--%c\tb--%c\tc--%c \n",i,j,k);
29                     }
30                 }
31             }
32         }
33     }
34     
35     return 0;
36 }
复制代码

函数区间求最大值(方法)

复制代码
 1 /*
 2 编程:设x取值为区间[1,20]的整数,求函数f(x)=x-sin(x)- cos(x)的最大值
 3 要求使用自定义函数实现f(x)功能
 4 */
 5 
 6 /*
 7 *  @author: 成鹏致远 
 8 *  @net: http://infodown.tap.cn
 9 */
10 
11 #include "stdio.h"
12 #include "math.h"
13 double f()
14 {
15    int i;
16    double max=0,x;
17    for(i=1;i<=20;i++)
18    {
19      x=i-sin(i)-cos(i);
20      if(x-max>1e-6)
21        max=x;
22    }
23    return max;
24 
25 }
26 main()
27 {
28     printf("%lf",f());
29     getchar();
30 }
复制代码

分解质因数

复制代码
 1 /*
 2 题目:将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。
 3 程序分析:对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成:
 4 (1)如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。
 5 (2)如果n<>k,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数你n,
 6   重复执行第一步。
 7 (3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。
 8 */
 9 
10 #include <stdio.h>
11 #include <math.h>
12 
13 main()
14 {
15     int n,i;
16     printf("please input a number:\n");
17     scanf("%d",&n);
18     printf("%d=",n);
19     for(i=2;i<=sqrt(n);i++)
20     {
21         while(n!=i)
22         {
23             if(n%i==0)
24             {
25                 printf("%d*",i);
26                 n=n/i;
27             }
28             else
29                 break;
30         }
31     }
32     printf("%d \n",n);
33 }
复制代码

古代买鸡问题

复制代码
 1 /*
 2 编程解决如下问题:鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一。
 3 百钱买百鸡,问鸡翁,鸡母,鸡雏各几何?
 4 
 5 解决方案:数学问题,先用数学方法解决
 6 1、设鸡翁、鸡母、鸡雏分别a、b、c只
 7 2、5a+3b+c/3=100
 8 3、a+b+c=100
 9 4、解得:b=(100-7*a)/4;
10        c=(300+3*a)/4;
11 
12 */
13 
14 /*
15 *  @author: 成鹏致远 
16 *  @net: http://infodown.tap.cn
17 */
18 
19 #include<stdio.h>
20 
21 void main()
22 {
23     int a,b,c;
24     for(a=0;a<20;a++)
25     {
26         b=(100-7*a)/4;
27         c=(300+3*a)/4;
28         if(a+b+c==100&&a>=0&&b>=0&&c>=0)
29         {
30                 printf("%d,%d,%d\n",a,b,c);
31         }
32     }
33 }
复制代码

字符串交叉连接

复制代码
 1 //输入两个字符串,要求将这两个字符串交叉连接。如串1为"ABCD",串2为"123456",则合并后的串为"A1B2C3D456"。
 2 
 3 /*
 4 *  @author: 成鹏致远 
 5 *  @net: http://infodown.tap.cn
 6 */
 7 
 8 #include<stdio.h>
 9 #include<stdlib.h>   
10 void main()
11 {
12     char a[20],s[20],*p1,*p2;
13     gets(a);
14     gets(s);
15     p1=a;
16     p2=s;
17     while(1)
18     {
19         if(*p1!='\0')
20         {    
21             printf("%c",*p1);p1++;
22         }
23         if(*p2!='\0')
24         {
25             printf("%c",*p2);
26             p2++;
27         }
28         if(*p1=='\0' && *p2=='\0')
29             exit(0);
30     }
31 }
复制代码

完数

复制代码
 1 /*
 2 题目:一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如6=1+2+3.编程
 3     找出1000以内的所有完数。
 4 */
 5 
 6 /*
 7 *  @author: 成鹏致远 
 8 *  @net: http://infodown.tap.cn
 9 */
10 
11 #include <stdio.h>
12 
13 int main(void)
14 {
15     static int k[10];
16     int i,j,n,s;
17     for(j=2;j<1000;j++)
18     {
19         n=-1;
20         s=j;
21         for(i=1;i<=j/2;i++)
22         {
23             if((j%i)==0) //因子
24             {
25                 n++;
26                 s=s-i; //减到0则是完数
27                 k[n]=i;
28             }
29         }
30         if(s==0)
31         {
32             printf("%d 是一个完数 \n%d=",j,j);
33             for(i=0;i<n;i++)
34                 printf("%d+",k[i]);
35             printf("%d \n",k[n]);
36         }
37     }
38 
39     return 0;
40 }
复制代码

容器分水移动(算法)

复制代码
 1 /*
 2 编程解决如下数学问题:有12升水,怎样利用一个8升
 3 和一个5升的容器将水分为两个6升?要求以如下格式
 4 打印出分水步骤。
 5 a12  b8  c5
 6 12   0   0
 7 *    *   * ( “*”表示当前状态下每个容器的盛水量)
 8 ......
 9 6   6   0
10 */
11 
12 /*
13 *  @author: 成鹏致远 
14 *  @net: http://infodown.tap.cn
15 */
16 
17 #include <stdio.h>
18 
19 
20 void move(int *ai,int *aj,int aiContainer,int ajContainer) //将油从一个容器导倒入另外一个容器
21 {      //移动容器目前盛水量,接收容器目前盛水量,移动容器容量,接收容器容量
22 
23     if(aiContainer>ajContainer) //移动容器容量>接收容器容量
24     {
25         if(*ai+*aj>ajContainer) //将油倒入接收容器中,移动容器有剩余
26         {
27             *ai=*ai-(ajContainer-*aj);
28             *aj=*aj+ajContainer-*aj;
29         }
30         else //将油倒入接收容器中,移动容器无剩余
31         {
32             *aj=*ai+*aj; 
33             *ai=*ai-*ai;
34         }
35     }
36     else //移动容器容量<接收容器容量,则全部倒入接收容器中
37     {
38         *aj=*ai+*aj;
39         *ai=0;
40     }
41 }
42 
43 int main(void)
44 {
45     int a[3]={12,0,0},i,m=0;
46     int container[3]={12,8,5};
47     printf("%-8s%-8s%-8s\n","a12","b8","c5");
48     printf("%-8d%-8d%-8d\n",a[0],a[1],a[2]);
49     while(a[0]!=6)
50     {
51         for(i=0;i<3;i++)//循环三次,分别从a->b,b->c,c->a
52         {
53             move(&a[i],&a[(i+1)%3],container[i],container[(i+1)%3]);
54             m++;
55             printf("%-8d%-8d%-8d\n",a[0],a[1],a[2]);
56             if(a[0]==6 && a[1]==6)
57             {
58                 printf("The total number is %d to reach success!",m);
59                 getchar();
60                 return 0;
61             }
62         }
63         move(&a[1],&a[2],container[1],container[2]);//b->c
64         printf("%-8d%-8d%-8d\n",a[0],a[1],a[2]);
65         m++;
66         if(a[0]==6 && a[1]==6)
67         {
68             printf("The total number is %d to reach success!",m);
69             break;
70         }
71     }
72     getchar();
73     return 0;
74 }
复制代码

猴子吃桃问题(逆向思维)

复制代码
 1 /*
 2 猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个
 3     第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下
 4     的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。
 5 1.程序分析:采取逆向思维的方法,从后往前推断。
 6 */
 7 
 8 /*
 9 *  @author: 成鹏致远 
10 *  @net: http://infodown.tap.cn
11 */
12 
13 #include <stdio.h>
14 
15 int main(void)
16 {
17     int day,x1,x2;
18     day=9;
19     x2=1;
20     while(day>0)
21     {
22         x1=(x2+1)*2;
23         x2=x1;
24         day--;
25     }
26     printf("the total is %d \n",x1);
27 
28     return 0;
29 }
复制代码

统计字符数字等

复制代码
 1 /*
 2 题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数
 3 */
 4 
 5 /*
 6 *  @author: 成鹏致远 
 7 *  @net: http://infodown.tap.cn
 8 */
 9 
10 #include <stdio.h>
11 
12 int main(void)
13 {
14     char c;
15     int letters=0,space=0,digit=0,others=0;
16     printf("please input some characters: \n");
17     while((c=getchar())!='\n')
18     {
19         if(c>='a'&&c<='z'||c>='A'&&c<='Z')
20             letters++;
21         else if(c==' ')
22             space++;
23         else if(c>='0'&&c<='9')
24             digit++;
25         else
26             others++;
27     }
28     printf("all in all:char=%d space=%d digit=%d others=%d \n",letters,space,digit,others);
29 
30     return 0;
31 }
复制代码

贪心算法用例(够纠结的)

复制代码
  1 /*
  2 编程解决如下问题。
  3   请在整数n=742683613984中删除8个数字,使得余下的数字按原次序组成的新数最小。要求如下:
  4   (1)整数n和删除数字的个数“8”在源程序中完成赋值,程序直接输出运行结果;
  5   (2)程序结果输出先后被删除的数字(之间以逗号分隔)和删除后所得的最小数。
  6   (提示:整数n可以以字符数组的方式定义、赋值和处理)
  7 
  8   编写思路:
  9   在前9位数字中寻找最小数字a1,记下该最小数字的位置b1,a1前面所有数字是该删除的,
 10   个数m=b1-1,然后从a1后面开始继续操作,变为删除8-m个数字,从a1后8-m+1个数字中找最小值a2,
 11   记下b2,删除a1与a2之间的数字,个数b2-b1-1。m=m+b2-b1-1.如此下去直至m=8,停止操作,
 12   输出a1a2……及最后一个a和之后的数字。
 13 
 14   程序一是正确的,程序二是错误的
 15   一和二的差别主要是在删除字符序列的顺序上
 16 */
 17 
 18 /*
 19 *  @author: 成鹏致远 
 20 *  @net: http://infodown.tap.cn
 21 */
 22 
 23 //程序一:贪心算法
 24 
 25 #include <string.h>
 26 #include <stdio.h>
 27 
 28  int main()
 29 {
 30   int i,m=8,t=0;
 31   char p[10];
 32   char s[]="742683613984";
 33   for (i=0;i<12;i++)
 34   {
 35         while(t&&p[t-1]>s[i]&&m) //用p数组中的每一个元素和当前s[i]比较
 36         {
 37             t--,m--; //进入循环意味着s[i]比p[--t]小,需要将p[--t]输出,并且m-1
 38             printf("%c",p[t]);
 39             if(m) //未删除所有符合条件的元素之前,用逗号将各元素分开
 40             printf(",");
 41         }
 42         p[t++]=s[i]; //p数组依次暂存前一位比后一位小的数字
 43   } //循环结束后p数组中存储着最小的四位数
 44         p[t]=0; //字符数组结束
 45         printf("\n");
 46         puts(p);
 47         return 0;
 48 }
 49         
 50           
 51  
 52 /*
 53 //程序二:这个是错误的,程序一和程序二的差别在删除字符序列的顺序
 54 
 55     #include <stdio.h>
 56     #include <stdlib.h>
 57     
 58      void main()
 59      {
 60          char *s="742683613984";
 61          printf("%s\n",s); 
 62          //去掉8个相当于取4个
 63          int a,b,c,d;//下标
 64          int aa,bb,cc,dd;//某位数字
 65          int ka,kb,kc,kd;//最小值对应的下标
 66          int min=10000;//当取4个时,设定初始最小值为5位数
 67          int num;//组和的值
 68          for(a=0;a<=8;a++)
 69          {
 70              for(b=1;b<=9;b++)
 71              {
 72                  for(c=2;c<=10;c++)
 73                  {
 74                      for(d=3;d<=11;d++)
 75                      {
 76                          if((a<b)  && (b<c) && (c<d)  )//保证不重复和先后顺序
 77                          {
 78                              aa=s[a]-'0';bb=s[b]-'0';cc=s[c]-'0';dd=s[d]-'0';//字符型转换为整数
 79                              num=aa*1000+bb*100+cc*10+dd;//求组和数
 80                              if (num<min)//选择最小值以及下标
 81                              {
 82                                  min=num;
 83                                  ka=a;kb=b;kc=c;kd=d;//最小值对应的下标
 84                              }
 85                          }
 86                      }
 87                  }
 88              }
 89         }
 90      
 91      for(int i=0;i<=11;i++)//输出去掉的数
 92      {
 93          if(i!=ka && i!=kb && i!=kc && i!=kd)
 94              printf("%c\t",s[i]); 
 95      }
 96      printf("\n%d\n",min);//输出最小值 
 97      system("pause");
 98 }
 99 
100 
101 */
102   

posted on 2013-07-23 19:38  redmondfans  阅读(463)  评论(0编辑  收藏  举报