1. 十进制与二进制相互转换
#include <stdio.h>
#include <math.h>
int main(void)
{
int i, j, n, m; /*定义变量i, j, n, m*/
int a[16] = { 0 }; /*定义数组a,元素初始值为0*/
printf("please input the decimalism number(0~32767):\n");
scanf_s("%d", &n);
/*十进制转换为二进制*/
for (m = 0; m < 15; m++) /*for循环从0-14,最高位为符号位*/
{
i = n % 2;
j = n / 2;
n = j;
a[m] = i;
}
printf("二进制为:");
for (m = 15; m >= 0; m--) /*for循环,将数组中的16个元素从后往前输出*/
{
printf("%d", a[m]);
if (m % 4 == 0) /*每输出4个元素,输出一个空格*/
printf(" ");
}
/*二进制转换为十进制*/
for (m = 0, i = 0; m < 15; m++)
{
i += a[m]*pow(2, m);
}
printf("\n十进制为:%d", i);
return 0;
}
2. 三个数由小到大排序
任意输入三个整数,实现对这三个整数进行由小到大排序,并打印出来。
#include <stdio.h>
int main(void)
{
int a, b, c, t;
printf("please input a,b,c:\n");
scanf_s("%d%d%d", &a, &b, &c);
if (a > b)
{
t = a;
a = b;
b = t;
}
if (a > c)
{
t = a;
a = c;
c = t;
}
if (b > c)
{
t = b;
b = c;
c = t;
}
printf("the order of the number is:\n");
printf("%d,%d,%d", a, b, c);
return 0;
}
3. 计算某日是该年的第几天
编写一个程序,输入年、月、日,在屏幕中输出此日期是该年的第几天。
主要实现方法:
- 如何判断输入的年份是闰年还是平年。闰年判断标准为非整百年份能被4整除,整百年份能被400整除。
- 如何求出此日期是该年份的第几天。由于闰年的2月份和平年的不同,这里将闰年和平年12个月每月的天数分别存储在两个数组中。当输入年份是闰年,月份为m时,累加存储这闰年每月的天数的数组的前m-1个元素,并将结果加上输入的日期便求出了最终结果,平年的算法类似。
#include <stdio.h>
int leap(int a); /*用来指定年份是否为闰年*/
int number(int year, int m, int d); /*计算输入日期为该年的第几天*/
int main(void)
{
int year, month, day, n;
printf("请输入年月日\n");
scanf_s("%d%d%d", &year, &month, &day);
n = number(year, month, day);
printf("%d年%d月%d日,是该年的第%d天。\n", year, month, day, n);
return 0;
}
int leap(int a)
{
if (a % 4 == 0 && a % 100 != 0 || a % 400 == 0) /*闰年判定条件*/
return 1;
else
return 0;
}
int number(int year, int m, int d)
{
int sum = 0, i;
int a[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; /*存放平年每月的天数*/
int b[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; /*存放闰年每月的天数*/
if (leap(year) == 1)
for (i = 0; i < m - 1; i++)
sum += b[i];
else
for (i = 0; i < m - 1; i++)
sum += a[i];
sum += d;
return sum;
}
4. 猴子摘桃
猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将第一天剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上再吃时,发现只剩下一个桃子。求猴子第一天共摘了多少个桃子?
主要思路
- 首先要明确第一天桃子数和第二天桃子数之间的关系,即第二天桃子数加1的2倍等于第一天的桃子数。
- 使用while语句从后往前推出第一天摘的桃子数。
#include <stdio.h>
int main(void)
{
int day, x1, x2;
day = 9;
x2 = 1;
while (day > 0)
{
x1 = (x2 + 1) * 2; /*第二天桃子数加1的2倍等于第一天的桃子数*/
x2 = x1;
day--;
}
printf("the total is %d\n", x1);
return 0;
}
5. 婚礼上的谎言
三对情侣参加婚礼,三个新郎为A,B,C,三个新娘为X,Y,Z,有人想知道究竟谁和谁结婚,于是就问新人中的三位,得到如下的提示:A说他将和X结婚;X说她的未婚夫是C;C说他将和Z结婚。这人事后知道他们在开玩笑,说的全是假话,那么究竟是谁与谁结婚呢?
主要思路
- 用“x = 1”表示A和新娘x结婚,同理,如果新郎A不与新娘X结婚则写成“x != 1”,于是得到以下关系:
“x != 1” A不与X结婚.
“x != 3” C不与X结婚
“z != 3” C不与Z结婚
- 三位新娘不能互为配偶,则x != y 且 x != z 且 y != z
- 穷举所有可能的情况,带入上述表达式进行推理运算。如果假设和情况使上述表达式的结果为真,则假设的情况就是正确的结果。
- 当新郎的代号的值与新娘代号的值相等时,即为结婚对象
#include <stdio.h>
int main(void)
{
int x, y, z; /*x, y, z为新娘X,Y,Z代号的值*/
int A = 1, B = 2, C = 3; /*A,B,C为新郎的代号*/
printf("A = 1, B = 2, C = 3\n");
for (x = 1; x <= 3; x++)
for (y = 1; y <= 3; y++)
for (z = 1; z <= 3; z++)
if (x != 1 && x != 3 && z != 3 && x != y && x != z && y != z)
{
printf("X = %d, ", x);
printf("Y = %d, ", y);
printf("Z = %d\n" , z);
}
printf("代号相等即为结婚对象!");
}
- 运行结果如下
6. 百钱买百鸡
中国古代数学家张丘建在他的《算经》中提出了一个著名的“百钱买百鸡问题”:鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一,百钱买百鸡,问翁、母、雏各几何?
主要思路
- 根据描述,可以计算出:如果只买公鸡,一百元最多买20只;如果只买母鸡,最多只能买33只;若只买小鸡,根据“鸡雏三,值钱一”,说明小鸡最少买3只,最多买99只。
- 也就是说公鸡的范围是0-20,母鸡的范围是0-33,小鸡的范围是3-99.
- 判断条件:钱数是否为100;三种鸡的数量是否为100,小鸡的数量是够能被3整除
int main(void)
{
int cock, hen, chick;
for (cock = 0; cock <= 20; cock++) /*公鸡范围在0-20之间*/
for (hen = 0; hen <= 33; hen++) /*母鸡范围在0-33之间*/
for (chick = 3; chick <= 99; chick++) /*小鸡范围在3-99之间*/
if ((5 * cock + 3 * hen + chick / 3 == 100) && (cock + hen + chick == 100) && (chick % 3 == 0)) /*判断钱数是否等于100,购买的鸡数是否等于100,小鸡数是否能被3整除*/
printf("公鸡:%-5d 母鸡:%-5d 小鸡:%-5d\n", cock, hen, chick); /*负号表示左对齐*/
return 0;
}
- 运行结果
7. 打鱼晒网问题
如果一个渔夫从2011年1月1日开始每三天打一次鱼,两天晒一次网。实现输入2011年1月1日以后的任意一个日期,得到该渔夫是打鱼还是在晒网。
主要思路
- 判断渔夫是打鱼还是在晒网,其实就是在计算日期,然后推算出渔夫当天是在打鱼还是在晒网。
- 判断输入年份是否为闰年。闰年有366天,平年有365天。
- 求出输入日期距2011年1月1日有多少天。
#include <stdio.h>
int leap(int a); /*判断输入年份是否为闰年*/
int number(int year, int month, int day); /*用来计算输入日期距2011年1月1日共有多少天*/
int main(void)
{
int year, month, day, n;
printf("请输入年月日:\n");
scanf_s("%d%d%d", &year, &month, &day);
n = number(year, month, day);
if ((n % 5) < 4 && (n % 5 > 0)) /*当余数为1或2或3时说明在打鱼,否则在晒网*/
printf("%d.%d.%d: 打鱼\n", year, month, day);
else
printf("%d.%d.%d: 晒网\n", year, month, day);
}
int leap(int a)
{
if (a % 4 == 0 && a % 100 == 0 || a % 400 == 0)
return 1;
else
return 0;
}
int number(int year, int month, int day)
{
int sum = 0, i, j;
int a[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; /*数组a用来存放平年每月的天数*/
int b[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; /*数组b用来存放闰年每月的天数*/
if (leap(year) == 1)
for (i = 0; i < month - 1; i++)
sum += b[i];
else
for (i = 0; i < month - 1; i++)
sum += a[i];
for (j = 2011; j < year; j++)
if (leap(year) == 1)
sum += 366; /*2011年到输入年份是闰年的加366*/
else
sum += 365; /*2011年到输入年份不是闰年的加365*/
sum += day; /*将前面累加的结果加上日期,求出总天数*/
return sum;
}
- 运行结果
8. 小球下落问题
一个小球从100米高度自由落下,每次落地后反跳回原高度的一半,再落下;那么它在第10次落地时,共经过多少米?第10次反弹多高?
主要思路
- 从100米高处落下到第一次落地,单独考虑;
- 从第一次弹起到第二次落地时所经过的路程为前一次弹起最高高度的一半乘以2再加上前面经过的路程。(每次都有弹起和下落两个过程,所以小球经过的路程相等,要乘以2。)
- 以此类推,到第十次落地时,共经过了九次这样的弹起落下的过程。
- 第十次反弹的高度即为第九次弹起高度的一半。
#include <stdio.h>
int main(void)
{
float i, h = 100, s = 100;
for (i = 1; i <= 9; i++) /*1-9表示小球从第二次落地到第十次落地*/
{
h = h / 2; /*每次落地弹起的高度为上一次的一半*/
s += h * 2; /*累积的高度加上下一次落地后弹起与下落的高度*/
}
printf("总长度是:%f\n", s);
printf("第十次落地后弹起的高度是:%f\n", h / 2);
return 0;
}
- 运行结果
9. 巧分苹果
一家农户以果园为生。一天,父亲推出一车苹果,共2520个,准备分给他的6个儿子。父亲先按事先写在一张纸上的数字把这堆苹果分完,每个人分到的苹果的个数都不相同。然后他说:“老大,把你分到的苹果分1/8给老二,老二拿到后,连通原来的苹果分1/7给老三,老三拿到后,连通原来的苹果分给1/6给老四。以此类推,最后老六拿到后,联通原来的苹果分1/3给老大,这样,你们每个人分到的苹果就一样多了。”那么兄弟6人原来各分到多少个苹果?
主要思路
- 设xi(i = 1、2、3、4、5、6)依次为6个兄弟原来分到的苹果数;
- 设yi(i = 2、3、4、5、6)为除老大外其余五兄弟从哥哥那里得到还未分给弟弟时的苹果数;
y2 = x2 + (1/8) * y1
s = y2 * (6/7)
y3 = x3 + (1/7) * y2
s = y3 * (5/6)
y4 = x4 + (1/8) * y3
s = y4 * (4/5)
y5 = x5 + (1/8) * y4
s = y5 * (3/4)
y6 = x6 + (1/8) * y5
s = y6 * (2/3)
- 老大是个特例,即x1 = y1;
s = x1 * (7/8) + y6 * (1/3)
- 利用循环和数组先求出从哥哥那里分来的苹果却未分给弟弟时的数目,在在数目的基础上再求原来没人分到的苹果个数。
#include <stdio.h>
int main(void)
{
int x[7], y[7], s, i;
s = 2520 / 6; /*求出平均每人分到的苹果数*/
for (i = 2; i <= 6; i++)
y[i] = s * (9 - i) / (8 - i);
y[1] = x[1] = (s - y[6] / 3) * 8 / 7;
for (i = 2; i <= 6; i++) /*求老二到老六得到哥哥分来的苹果却未分给弟弟时的苹果数*/
x[i] = y[i] - y[i - 1] / (10 - i); /*老大得到老六分来的苹果却未分给弟弟时的苹果数*/
for (i = 1; i <= 6; i++)
printf("x[%d]=%d\n", i, x[i]); /*求原来没人分到的苹果数*/
return 0;
}
- 运行结果