目录
P16_习题1-6_三角形
P16_习题1-7_年份
P20_eg2-1_aabb
为什么是int n = a*1100 + b*11
为什么要将向下取整?
P22_eg2-2_3n+1问题
P24_eg2-3_近似计算
P25_eg2-4_阶乘之和
P27_eg2-5_数据统计
P34_习题2-1_水仙花数
P34_习题2-2_韩信点兵
P34_习题2-3_倒三角形
P35_习题2-4_子序列的和
P35_习题2-5_分数化小数
P35_习题2-6_排列
P40_蛇形填数
sprintf
P43_竖式问题
P16_习题1-6_三角形
输入三角形3条边的长度值(均为正整数),判断是否能为直角三角形的3个边长。
#include<stdio.h>
int main(){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
if(a+b > c && a+c > b && b+c > a){
if(a*a+b*b == c*c || a*a+c*c == b*b || b*b+c*c == a*a){
printf("yes\n");
} else {
printf("no\n");
}
} else {
printf("not a traingle\n");
}
}
P16_习题1-7_年份
#include<stdio.h>
int main()
{
int i = 0;
for (i = 2000; i <= 2500; i++)
{
if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0)
{
printf("%d是闰年 ", i);
}
}
return 0;
}
P20_eg2-1_aabb
输出所有形如aabb的4位完全平方数(即前两位数字相等,后两位数字也相等)。
#include<stdio.h>
#include<math.h>
int main(){
for(int a = 1;a <= 9;a++){
for(int b = 0;b <= 9;b++){
int n = a*1100 + b*11;
int m = floor(sqrt(n) + 0.5);
if(m*m == n){
printf("%d\n",n);
}
}
}
return 0;
}
为什么是int n = a*1100 + b*11
通过枚举,我们要构造出形如aabb的四位数,一个一位数a*1100就是aa00,一个一位数b*11就是bb
为什么要将向下取整?
可不可以这样写?if(sqrt(n)==floor(sqrt(n)))printf("%d\n",n),
即直接判断sqrt(n)是否为整数。理论上当然没问题,但这样写不保险,因为浮点数的运算(和函数)
有可能存在误差。
假设在经过大量计算后,由于误差的影响,整数1变成了0.9999999999,floor的结果会
是0而不是1。为了减小误差的影响,一般改成四舍五入,即floor(x+0.5)。如果难以理
解,可以想象成在数轴上把一个单位区间往左移动0.5个单位的距离。floor(x)等于1的区间
为[1,2),而floor(x+0.5)等于1的区间为[0.5,1.5)。
P22_eg2-2_3n+1问题
对于任意大于1的自然数n,若n为奇数,则将n变为3n+1,否则变为n的一半。
#include<stdio.h>
int main(){
int n2,count = 0;
scanf("%d",&n2);
long long n = n2;//防止乘法溢出
while(n > 1){
if(n % 2 == 1){
n = n*3 + 1;
} else {
n /= 2;
count++;
}
}
printf("%d\n",count);
return 0;
}
P24_eg2-3_近似计算
计算PI/4 = 1-1/3+1/5-1/7+……
#include<stdio.h>
int main(){
double sum = 0;
for(int i = 0;;i++){
double term = 1.0 / (i*2+1);
if(i % 2 == 0){
sum += term;
} else {
sum -= term;
}
if(term < 1e-6){
break;
}
}
printf("%.6f\n",sum);
return 0;
}
P25_eg2-4_阶乘之和
输入n,计算S=1!+2!+3!+……+n!的末6位
#include<stdio.h>
int main(){
int n,S = 0;
scanf("%d",&n);
for(int i = 1;i <= n;i++){
int factorial = 1;
for(int j = 1;j <= i;j++){
factorial *= j;
}
S += factorial;
}
printf("%d\n",S % 1000000);
return 0;
}
P27_eg2-5_数据统计
输入一些整数,求出它们的最小值、最大值和平均值(保留3位小数)。输入保证这些数都是不超过1000的整数
(以下程序的前提是:程序的目录下要有data.in文件)
#define LOCAL
#include<stdio.h>
#define INF 1000000000
int main(){
#ifdef LOCAL
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
#endif
int x,n = 0,min = INF,max = -INF,s = 0;
while(scanf("%d",&x) == 1){
s += x;
if(x < min) min = x;
if(x > max) max = x;
// printf("x = %d,min = %d,max = %d\n",x,min,max);
n++;
}
printf("%d %d %.3f\n",min,max,(double)s/n);
return 0;
}
P34_习题2-1_水仙花数
100-999水仙花数,ABC = A^3+B^3+C^3
#include<stdio.h>
int main(){
for(int n = 100;n <= 999;n++){
int a = n/100;
int b = n/10%10;
int c = n%10;
if(n == a*a*a + b*b*b + c*c*c){
printf("%d\n",n);
}
}
return 0;
}
P34_习题2-2_韩信点兵
相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、
七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了。输入包含多组数据,
每组数据包含3个非负整数a,b,c,表示每种队形排尾的人数(a < 3,b < 5,c < 7)
输出总人数的最小值(或报告无解)。已知总人数不小于10,不超过100。
样例输入:
2 1 6
2 1 3
样例输出:
41
No answer
#include<stdio.h>
int main(){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
for(int i = 10;i <= 100;i++){
if(i%3 == a && i%5 == b && i%7 == c){
printf("%d\n",i);
return 0;
}
}
printf("No answer\n");
return 0;
}
P34_习题2-3_倒三角形
输入正整数n<20 || n == 20,输出一个n层的倒三角形。例如,n=5时输出如下:
#########
#######
#####
###
#
#include<stdio.h>
int main(){
int n;
scanf("%d",&n);
if(n >= 0 && n <= 20){
for(int i = 0;i < n;i++){
for(int m = 0;m < i;m++){
printf(" ");
}
for(int j = 0;j < 2*n-1-2*i;j++){
printf("#");
}
printf("\n");
}
} else {
printf("ERROR\n");
}
}
P35_习题2-4_子序列的和
输入两个整数n<m<10^6,输出1/n^2+1/(n+1)^2+……+1/m^2,保留5位小数。输入包含多组数据,结束标记为
n=m=0
样例输入:
2 4
65536 655360
0 0
样例输出:
0.42361
0.00001
#include<stdio.h>
int main(){
int n,m;
scanf("%d%d",&n,&m);
double sum = 0;
for(double i = n;i <= m;i++){
sum += 1/(i*i);
}
printf("%.5f",sum);
return 0;
}
本题的特点就是int类型变量和double类型变量的比较。要清楚:谁是int类型,谁是double类型
if(1.0 == 1) printf("yes");
输出:
yes
P35_习题2-5_分数化小数
输入正整数a,b,c,输出a/b的小数形式,精确到小数点后c位。a,b<=10^6,c<=100
输入包含多组数据,结束标记为a=b=c=0
样例输入:
1 6 4
样例输出:
0.1667
(暂时就这样吧,用C嘎嘎的接口)
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<cmath>
using namespace std;
void Fraction_To_Decimal( double x, int n);
int main(){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
double a1 = a,b1 = b;
double decimal = a1/b1;
Fraction_To_Decimal(decimal,c);
return 0;
}
void Fraction_To_Decimal( double x, int n){
cout <<fixed << setprecision(n) <<x << endl;
}
P35_习题2-6_排列
用1,2,3……,9组成3个三位数abc,def和ghi,每个数字恰好使用一次,要求abc:def:ghi=1:2:3
按照“abc def ghi”的格式输出所有解,每行一个解
#include<stdio.h>
int main(){
int count = 0;
for(int i = 100;i <=999;i++){
for(int j = 100;j <=999;j++){
for(int k = 100;k <=999;k++){
double i1 = i,j1 = j,k1 = k;
if(j1/i1 == 2 && k1/i1 == 3 && k1/j1 == 1.5){
++count;
printf("%d %d %d\n",i,j,k);
}
}
}
}
printf("%d",count);
return 0;
}
由于if内的除法会出现小数,所以要用三个double类型变量接收三个位上数字
double i1 = i,j1 = j,k1 = k;
if(j1/i1 == 2 && k1/i1 == 3 && k1/j1 == 1.5){}
P40_蛇形填数
在nxn方阵里填入1,2,……,nxn,要求填成蛇形。例如,n = 4时方阵为:
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
#include<stdio.h>
#include<string.h>
#define maxn 20
int a[maxn][maxn];
int main(){
int n,x,y,t = 0;
scanf("%d",&n);
memset(a,0,sizeof(a));
t = a[x = 0][y = n-1] = 1;
while(t < n*n){
while(x+1<n && !a[x+1][y]) a[++x][y] = ++t;
while(y-1>=0 && !a[x][y-1]) a[x][--y] = ++t;
while(x-1>=0 && !a[x-1][y]) a[--x][y] = ++t;
while(x+1<n && !a[x][y+1]) a[x][++y] = ++t;
}
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++){
printf("%3d",a[i][j]);
}
printf("\n");
}
return 0;
}
1、是否越界:x+1 < n,因为y的值没有修改;
2、继续走下去会不会到达一个已经填过的格子:下一个格子是(x+1,y),因此需要“a[x+1][y] == 0”
sprintf
#include<stdio.h>
#include<string.h>
int main(){
char buf[20];
sprintf(buf,"%d%d",100,99);
int len = strlen(buf); //strlen(buf)返回unsigned long int
for(int i = 0;i < len;i++){
printf("%c ",buf[i]);
}
return 0;
}
P43_竖式问题
找出所有形如abc*de(三位数乘以两位数)的算式,使得在完整的竖式中,
所有数字都属于一个特定的数字集合。 输入数字集合(相邻数字之间没有空格),输出所有
竖式。 每个竖式前应有编号,之后应有一个空行。 最后输出解的总数。
样例输入:
2557
样例输出:
<1>
..775
x..33
_____
.2325
2325.
_____
25575
#include<stdio.h>
#include<string.h>
int main(){
int count = 0;
char s[20],buf[99];
scanf("%s",s);
for(int abc = 100;abc <= 999;abc++){
for(int de = 10;de <= 99;de++){
int x = abc*(de%10),y = abc*(de/10),z = abc*de;
sprintf(buf,"%d%d%d%d%d",abc,de,x,y,z);
int ok = 1;
int len = strlen(buf);
for(int i = 0;i < len;i++){
if(strchr(s,buf[i]) == NULL){
ok = 0;
}
}
if(ok){
printf("<%d>\n",++count);
printf("%5d\nx%4d\n_____\n%5d\n%4d\n_____\n%5d\n\n",abc,de,x,y,z);
}
}
}
printf("Solution is %d",count);
return 0;
}
strchr:
char *strchr(const char *string,int c) 是在字符string 中寻找第一个出现的字符c 并返回位置