本文适合对 c c c 语言感兴趣的初学者,文字浅显易懂,没有太多晦涩的言语,也是作者的亲(瞎)身(编)经(乱)历(造),希望对刚入大学,想在程序方面有所建树的有志青年有所帮助。
当然, c c c 语言大佬也可以当成是茶余饭后的调味剂前来消遣,作者在此不做阻止。
#include // (1)
int main() {
int a, b;
while ( scanf("%d %d", &a, &b) != EOF) {
// (2)
printf("%d\n", a + b); // (3)
};
return 0;
}
stdio.h
是最基本的头文件,需要用到的一些输入输出的函数都是在这里声明的,所以需要把它包含进来;scanf
就是输入函数,因为计算机不知道你要输入的是数字还是字符串还是别的什么东西,所以需要规定输入的格式化类型,%d
代表整数, %f
代表小数,%s
代表字符串等等;因为计算机不知道什么时候结束输入,所以还有个返回值来告诉你不需要再输入了,即如果返回 EOF
,代表不会再有输入了。这里的EOF
其实就是个数字,值为 -1;printf
就是输出函数,这里就是把 a + b
的值通过给定的格式输出出来;【例题2】输入一个百分制的成绩 t t t,将其转换成对应的等级,具体转换规则如下:90 ~ 100为 A; 80 ~ 89为 B; 70 ~ 79为 C; 60 ~ 69为 D; 0 ~ 59为 E;
#include
int main() {
int v;
while (scanf("%d", &v) != EOF) {
if (v < 0 || v > 100) {
printf("Score is error!\n"); // (1)
}
else {
if (v >= 0 && v <= 59) {
printf("E\n"); // (2)
}
else if (v == 100) {
printf("A\n"); // (3)
}
else{
// (4)
char c = 'D' - (v - 60) / 10;
printf("%c\n", c);
}
}
}
return 0;
}
'B' + 1 = 'C'
以及 'C' + 1 = 'D'
,所以分数和等级的关系可以表示成:【例题3】给定 n ( n ≤ 1000 ) n(n \le 1000) n(n≤1000),然后给出 n n n 个整数坐标 ( x i , y i ) (x_i, y_i) (xi,yi),坐标范围 ( − 100 < x i , y i < 100 ) (-100 < x_i, y_i < 100) (−100<xi,yi<100) 求距离学校最近的坐标的距离,精确到小数点后 3 位(假设 学校的位置在原点)。
#include
#include // (1)
const int maxd = 1e9;
int distSqr(int x, int y) {
return x * x + y * y;
}
int main() {
int n, x, y;
while (scanf("%d", &n) != EOF) {
int minD = maxd;
for (int i = 0; i < n; ++i) {
// (2)
scanf("%d %d", &x, &y);
int d = distSqr(x, y);
if (d < minD)
minD = d;
}
printf("%.3lf\n", sqrt(minD + 0.0)); // (3)
}
return 0;
}
math.h
;for(init; condition; action)
是 c c c 中基础的循环遍历语句,init
部分一般写一些变量初始化;condition
是循环得以继续维持的条件判断;action
一般是对循环变量进行改变,从而改变condition
的真假。循环遍历输入,对输入的坐标选择距离平方最小的。sqrt
函数进行一次取值。例如:sqrt(9.0)=3
。【例题4】给定 n ( 2 ≤ n ≤ 1000 ) n(2 \le n \le 1000) n(2≤n≤1000),然后给出 n n n 个整数坐标 ( x i , y i ) (x_i, y_i) (xi,yi),坐标范围 ( − 100 < x i , y i < 100 ) (-100 < x_i, y_i < 100) (−100<xi,yi<100),求任意两个坐标中距离最小的,精确到小数点后 3 位。
#include
#include
const int maxn = 1024;
const int maxd = 1e9;
int distSqr(int x, int y) {
return x * x + y * y;
}
int x[maxn], y[maxn];
int main() {
int n;
while (scanf("%d", &n) != EOF) {
int minD = maxd;
for (int i = 0; i < n; ++i) {
scanf("%d %d", &x[i], &y[i]); // (1)
}
for(int i = 0; i < n; ++i) {
// (2)
for(int j = i + 1; j < n; ++j) {
int d = distSqr(x[i], y[i]);
if (d < minD)
minD = d;
}
}
printf("%.3lf\n", sqrt(minD + 0.0));
}
return 0;
}
a[i]
代表第 i+1
个元素。struct
。【例题5】给定 n ( 2 ≤ n ≤ 1000 ) n(2 \le n \le 1000) n(2≤n≤1000),然后给出 n n n 个整数坐标 ( x i , y i ) (x_i, y_i) (xi,yi),坐标范围 ( − 100 < x i , y i < 100 ) (-100 < x_i, y_i < 100) (−100<xi,yi<100),求任意两个坐标间距离最小的,精确到小数点后 3 位(利用结构体存储坐标)。
于是代码可以进行如下修改:
1)可以定义一个结构体叫Point
,然后把x,y
这两个变量放在这个结构体里;
2)两个Point
的距离可以定义结构体函数来实现;
#include
#include
const int maxn = 1024;
const int maxd = 1e9;
int Sqr(int x) {
return x * x;
}
struct Point {
int x, y;
void read() {
scanf("%d %d", &x, &y); // (1)
}
int distSqr(const Point& o) {
// (2)
return Sqr(x - o.x) + Sqr(y - o.y);
}
}P[maxn];
int main() {
int n;
while (scanf("%d", &n) != EOF) {
int minD = maxd;
for (int i = 0; i < n; ++i) {
P[i].read();
}
for(int i = 0; i < n; ++i) {
for(int j = i + 1; j < n; ++j) {
int d = P[i].distSqr(P[j]); // (3)
if (d < minD)
minD = d;
}
}
printf("%.3lf\n", sqrt(minD + 0.0));
}
return 0;
}
read
函数,放在结构体中进行定义;distSqr
函数,放在结构体中进行定义;当时的我,感觉自己已经是能闭上眼睛手撕十行代码的大神了。
【例题6】给定 n ( 2 ≤ n ≤ 1000 ) n(2 \le n \le 1000) n(2≤n≤1000),然后给出 n n n 个整数坐标 ( x i , y i ) (x_i, y_i) (xi,yi),坐标范围 ( − 100 < x i , y i < 100 ) (-100 < x_i, y_i < 100) (−100<xi,yi<100),求将坐标按照离原点距离从小到大输出。
sort
,调用它就可以轻松对数组的元素进行排序。而且代码也很短,我试着写了一下。#include
#include
#include // (1)
const int maxn = 1024;
const int maxd = 1e9;
int Sqr(int x) {
return x * x;
}
struct Point {
int x, y;
int dist;
void read() {
scanf("%d %d", &x, &y);
dist = Sqr(x) + Sqr(y);
}
bool operator < (const Point& o) const {
// (2)
return dist < o.dist;
}
void print() {
// (3)
printf("%d %d\n", x, y);
}
}P[maxn];
int main() {
int n;
while (scanf("%d", &n) != EOF) {
for (int i = 0; i < n; ++i) {
P[i].read();
}
std::sort(P, P + n); // (4)
for (int i = 0; i < n; ++i) {
P[i].print();
}
}
return 0;
}
algorithm
是 stl 的算法库,用sort
函数就需要包含这个库;dist
字段小的排在前面;print
封装到结构体中,封装一次是c++中的术语;std::sort
就是排序函数本体了,调用它就能将原数组 P P P 按照 dist
字段进行递增排序了;【例题7】输入一个十进制数 n ( n ≤ 2 30 ) n(n \le 2^{30}) n(n≤230),输出它的二进制表示;例如,十进制的 10 ,二进制表示为 1010;
#include
#include
using std::stack;
void convert(int n, stack<int>& st) {
if (n == 0)
st.push(0);
while (n) {
st.push(n % 2);
n /= 2;
}
}
void printStack(stack<int>& st) {
while (!st.empty()) {
printf("%d", st.top());
st.pop();
}
puts("");
}
int main() {
int n;
while (scanf_s("%d", &n) != EOF) {
stack <int> st;
convert(n, st); // (1)
printStack(st); // (2)
}
return 0;
}
【例题8】给定 n ( n ≤ 1 0 7 ) n(n \le 10^7) n(n≤107) 个数,求其中是 2 的幂 的数的个数。
&
表示)。所谓位与就是两个数 a a a 和 b b b 的二进制表示的每一位,从低位对位开始做与运算,只有两个位都为1,结果才为1,否则为0。如下所示:bool isPowerOfTwo(int n) {
return n && ( (n & (n-1)) == 0 );
}
【例题9】给定 n n n, m m m,请用 O ( 1 ) O(1) O(1) 的时间将一个数 n n n 的二进制第 m m m 位进行翻转。
^
表示)和左移( c c c 语言中用 <<
表示)。x << k
的用处就是将 x x x 的二进制所有位整体左移 k k k 位,并且低位补上 k k k 个 0。int turnOver(int n, int m) {
return n ^ (1<<m);
}
【例题10】给定 n ( n ≤ 9 ) n(n \le 9) n(n≤9), 按字典序输出 1 到 n n n 的所有全排列。
如下图所示,代表了一个 3个数的全排列的深度优先搜索空间树;
C++ 代码实现如下:
void dfs(int depth) {
// 1
if(depth == MAXN) {
// 2
dfs_print();
return;
}
for(int i = 1; i <= MAXN; ++i) {
int v = i;
if(!visit[v]) {
// 3
dfs_add(v); // 4
dfs(depth+1);
dfs_dec(v);
}
}
}
depth
参数用来做计数用,表明本次遍历了多少个结点;MAXN
个的时候,输出访问的元素列表;visit[v]
用来判断 v v v 这个元素是否有访问过;dfs_add
和 dfs_dec
分别表示将结点从访问列表加入和删除;