循环结构程序设计
尽量缩短变量的定义范围
四舍五入(把一个单位区间往左移动了0.5个单位的距离)
进行浮点数比较时,考虑浮点误差
#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); // 四舍五入,把一个单位区间往左移动了0.5个单位的距离 if(m*m == n) // 进行浮点数比较时,考虑浮点误差 printf("%d\n", n); } return 0; }
算数运算溢出
int32: -2147483648~2147483647
#include<stdio.h> int main() { int n, count = 0; scanf("%d", &n); while(n > 1) { if(n % 2 == 1) n = n*3+1; else n/=2; count++; // 计数器 } printf("%d\n", count); return 0; }
long long -2^63~2^63-1 cin/cout
#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; }
奇偶项
#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", sum); return 0; }
末六位
#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; }
要计算只包含+、-、*的整数表达式 / n的余数,可以在每步计算之后对n取余,结果不变
计时函数clock(),返回程序目前为止运行的时间 / CLOCKS_PER_SEC以s为单位
避免输入数据的时间影响测试结果——管道
Windows: echo 20 | test.c
Linux: echo 20 | ./test.c
程序效率低下!!!
#include<stdio.h> #include<time.h> int main() { const int mod = 1000000; 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 = (factorial * j % mod); // 要计算只包含+、-、*的整数表达式 / n的余数,可以在每步计算之后对n取余,结果不变 S = (S + factorial) % mod; } printf("%d\n", S); printf("Time used = %.2f\n", (double)clock() / CLOCKS_PER_SEC); // 计时函数clock(),返回程序目前为止运行的时间 / CLOCKS_PER_SEC以s为单位 return 0; }
输入的个数不确定
结束输入:Windows: Enter-->Ctrl+Z-->Enter
Linux: Ctrl+D
#include<stdio.h> int main() { int x, n = 0, min, max, s = 0; while(scanf("%d", &x) == 1) { // 输入的个数不确定 s += x; if(x < min) min = x; if(x > max) max = x; n++; } printf("%d %d %.3f\n", min, max, (double)s/n); return 0; }
了解文件读写的相关规定
文件输入输出:输入输出重定向,不能同时读写文件和标准输入输出
freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
文件比较:Windows: fc
Linux: diff
#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; }
在编译选项里定义LOCAL
文件输入输出,禁止重定向,fopen可以反复打开并读写文件
#include<stdio.h> #define INF 1000000000 int main() { FILE *fin, *fout; fin = fopen("data.in", "rb"); fout = fopen("data.out", "wb"); int x, n = 0, min = INF, max = -INF, s = 0; while(fscanf(fin, "%d", &x) == 1) { s += x; if(x < min) min = x; if(x > max) max = x; n++; } fprintf(fout, "%d %d %.3f\n", min, max, (double)s/n); fclose(fin); fclose(fout); return 0; }
改成标准输入输出,不要调用fopen和fclose
fin = stdin;
fout = stdout;
多组数据
鲁棒性,在数据有瑕疵的情况下仍然给出正确的结果
#include<stdio.h> #define INF 1000000000 int main() { int x, n = 0, min = INF, max = -INF, s = 0, kase = 0; // 当前数据编号 while(scanf("%d", &n) == 1 && n) { // 鲁棒性,在数据有瑕疵的情况下仍然给出正确的结果 int s = 0; for(int i = 0; i < n; i++) { scanf("%d", &x); s += x; if(x < min) min = x; if(x > max) max = x; } if(kase) printf("\n"); printf("Case %d: %d %d %.3f\n", ++kase, min, max, (double)s/n); } return 0; }
编译选项-Wall给出警告信息