在这个系列中,博主将会更新自己在学习C语言中做到的题目
目录
一.编写程序数一下 1到 100 的所有整数中出现多少个数字9
二.计算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值,打印出结果
六.编写代码在一个整形有序数组中查找具体的某个数(二分查找)
十三.求Sn=a+aa+aaa+aaaa+aaaaa的前5项之和,其中a是一个数字
一些选择题
1.
答案 D
表达式(++i)+(++i)+(++i),只有操作符的优先级和结合性,没法确定唯一计算路径
所以这个表达式可能因为计算顺序的差异导致结果是不一致的,所以表达式是错误的表达式。
可以在VS和Linux gcc测试,结果可能有差异。
2.
答案A
全局变量,没有给初始值时,编译其会默认将其初始化为0。
i的初始值为0,i--结果-1,i为整形,sizeof(i)求i类型大小是4,按照此分析来看,结果应该选择B,但是sizeof的返回值类型实际为无符号整形,因此编译器会自动将左侧i自动转换为无符号整形的数据,-1对应的无符号整形是一个非常大的数字,超过4或者8,故实际应该选择A
这道题其实很隐蔽,真是虾仁猪心!!!
3.
答案B
#include <stdio.h>
int main()
{
int a, b, c;
a = 5;
c = ++a;// ++a:加给a+1,结果为6,用加完之后的结果给c赋值,因此:a = 6 c = 6
b = ++c, c++, ++a, a++;
// 逗号表达式的优先级最低,这里先算b=++c, b得到的是++c后的结果,b是7
// b=++c 和后边的构成逗号表达式,依次从左向右计算的。
// 表达式结束时,c++和,++a,a++会给a+2,给c加1,此时c:8,a:8,b:7
b += a++ + c; // a先和c加,结果为16,在加上b的值7,比的结果为23,最后给a加1,a的值为9
printf("a = %d b = %d c = %d\n:", a, b, c); // a:9, b:23, c:8
return 0;
}
4.
答案 C
5.
答案B
6.
答案C
一些程序阅读题
1.
#include<stdio.h>
int main()
{
char a = -1;
signed char b = -1;
unsigned char c = -1;
printf("a=%d,b=%d,c=%d", a, b, c);
return 0;
}
这个程序的输出结果是什么
怎么理解?
补充:
1.char 到底是 signed char 还是 unsigned char ?
C语言标准并没有规定, 取决于编译器(但在大部分编译器,char就相当于unsigned char)
2.但是int 相当于 signed int 这是规定
2.
#include <stdio.h>
int main()
{
char a = -128;
printf("%u\n",a);
return 0;
}
分析:
注意:整型提升是按照原来的符号位提升的
3.
#include<stdio.h>
int main()
{
int i = -20;
unsigned int j = 10;
printf("%d\n", i + j);
return 0;
}
一.编写程序数一下 1到 100 的所有整数中出现多少个数字9
#include<stdio.h>
int main()
{
int i = 0;
int count = 0;
for (i = 1;i <= 100;i++)
{
if (i % 10 == 9)//个位是9
{
count++;
}
if (i / 10 == 9)//十位是9
{
count++;
}
}
printf("%d\n", count);
return 0;
}
二.计算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值,打印出结果
#include<stdio.h>
int main()
{
int i = 0;
double sum = 0;
int sign = 1;
for (i = 1;i <= 100;i++)
{
sum += sign * 1.0 / i;
sign = -sign;
}
printf("%lf\n", sum);
return 0;
}
三.计算并输出s的值。(用到阶乘和次方)
s的计算方法见下式,其中m为实数,其值由键盘读入。
计算时,要求最后一项的绝对值小于1e-4,输出结果保留两位小数。
#include<stdio.h>
#include<math.h>
int main()
{
double m = 0;
scanf("%lf", &m);
double fuc = 1.0;
double s = 0;
double a = m;//每项的值
int flag = 1;
int ret = 1;
int i = 0;
for (i = 1;fabs(a) >= 1e-4;i++)
{
ret *= i;
fuc*=m;
a= flag*fuc * 1.0 / ret;
s += a;
flag = -flag;
}
printf("%.2f", s);
return 0;
}
四.求10 个整数中最大值
#include<stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
int max = arr[0];
for (i = 0;i < 10;i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
printf("%d\n", max);
return 0;
}
五.在屏幕上输出9*9乘法口诀表
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1;i <= 9;i++)
{
int j = 0;
for (j = 1;j <= i;j++)
{
printf("%d*%d=%-2d ", i, j, i*j);
}
printf("\n");
}
return 0;
}
注意:-2d的-是向左对齐
六.编写代码在一个整形有序数组中查找具体的某个数(二分查找)
#include<stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7;
int left = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
int right = sz - 1;
int mid = 0;
int i = 0;
for (i = 0;i < 10;i++)
{
mid = (left + right) / 2;
if (arr[mid] < k)
{
left = mid + 1;
}
if (arr[mid] > k)
{
right = mid - 1;
}
if (arr[mid] == k)
{
printf("找到了,下标是%d\n", mid);
break;
}
}
if (i == 10)
{
printf("找不到\n");
}
return 0;
}
七.求两个数二进制中不同位的个数
//两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
int c = a^b;
int count = 0;
while (c)
{
c = c & (c - 1);
count++;
}
printf("%d\n", count);
return 0;
}
分析:
八.打印整数二进制的奇数位和偶数位
//打印整数二进制的奇数位和偶数位
#include<stdio.h>
void print(int m)
{
int i = 0;
//打印奇数位
for (i = 30;i>=0;i-=2)
{
printf("%d ", (m >> i) & 1);
}
printf("\n");
//打印偶数位
for (i = 31;i>=1;i-=2)
{
printf("%d ", (m >> i) & 1);
}
}
int main()
{
int n = 0;
scanf("%d", &n);
print(n);
return 0;
}
九.统计二进制中1的个数
版本一
//统计二进制中1的个数
#include <stdio.h>
int count_number_of_1(int m)
{
int c = 0;//计数器
while (m) //只要m不是0就有1
{
if (m % 2 == 1)
{
c++;
}
m /= 2;
}
return c;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = count_number_of_1(n);
printf("%d\n", ret);
return 0;
}
分析:
但是这个方法有局限性,就是只适用于正数,如果是负数就不行
所以我们需要对版本1的代码改进
我们把形参改成 unsigned int m 就可以了
但版本1还是不够好
版本二
#include <stdio.h>
int count_number_of_1(int m)
{
int count = 0;//计数器
int i = 0;
for (i = 0;i < 32;i++)
{
if (m&1==1)
{
count++;
}
m >>= 1;//右移1位
}
return count;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = count_number_of_1(n);
printf("%d\n", ret);
return 0;
}
但版本二还是不够优化,因为不管n有几个1,都循环32次
所以我们提出更高效的算法
版本三
#include<stdio.h>
int count_number_of_1(int m)
{
int count = 0;
while (m)
{
m = m & (m - 1);
count++;
}
return count;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = count_number_of_1(n);
printf("%d\n", ret);
return 0;
}
这是一种很巧妙的算法
分析:
十.交换两个变量(不创建临时变量)
看到题目,会觉得一头雾水,但其实这道题是要用到 ^ 异或操作符
//交换两个变量(不创建临时变量)
#include<stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("%d %d", a, b);
return 0;
}
然后我们这样分析:
十一.判断整数奇偶性
#include<stdio.h>
int main()
{
int i = 0;
while (scanf("%d", &i) != EOF)
{
if (i & 1 == 1)
{
printf("Odd\n");
}
else
printf("Even\n");
}
return 0;
}
这题不难,我们也可以写成
#include<stdio.h>
int main()
{
int i = 0;
while (scanf("%d", &i) != EOF)
{
if (i % 2 == 1)
{
printf("Odd\n");
}
else
printf("Even\n");
}
return 0;
}
但需要注意的是:
如果我们想要实现 一直输入
需要
while (scanf("%d", &i) != EOF)
或者
while (~scanf("%d", &i))
如果想停止时,按 ctrl+z
十二.判断元音辅音
有五个字母A(a), E(e), I(i), O(o),U(u)称为元音,其他所有字母称为辅音
请编写程序判断输入的字母是元音(Vowel)还是辅音(Consonant)
#include<stdio.h>
int main()
{
char V[] = { 'A','a','E','e','I','i','O','o','U','u' };
char ch = 0;
while (scanf("%c", &ch)!= EOF)
{
int i = 0;
for (i = 0;i < 10;i++)
{
if (ch == V[i])
{
printf("Vowel\n");
break;
}
}
if(i==10)
printf("Consonant\n");
}
return 0;
}
我们发现程序有误
原因:
scanf读取数据从缓冲区读取
输入时 a 回车 --> a \n
ch = a
然后 ch=\n
我们有三种解决办法:
1
用 getchar() 把 \n 拿走
#include<stdio.h>
int main()
{
char V[] = { 'A','a','E','e','I','i','O','o','U','u' };
char ch = 0;
while (scanf("%c", &ch)!= EOF)
{
int i = 0;
for (i = 0;i < 10;i++)
{
if (ch == V[i])
{
printf("Vowel\n");
break;
}
}
if(i==10)
printf("Consonant\n");
//清理缓冲区
getchar();
}
return 0;
}
2
%c前面加一个空格,这样每次就能把上一次输入的 '\n'拿走
十三.求Sn=a+aa+aaa+aaaa+aaaaa的前5项之和,其中a是一个数字
#include<stdio.h>
int main()
{
int a = 0;
scanf("%d", &a);
int tmp = 0;
int sum = 0;
int an = 0;//每项的值
int i = 0;
for (i = 0;i < 5;i++)
{
an = tmp * 10 + a;
tmp = an;
sum += an;
}
printf("%d", sum);
return 0;
}
分析:2 + 22 + 222 + 2222 + 22222
= 2+(2*10+2)+(22*10+2)...
十四.打印水仙花数
求出0~100000之间的所有“水仙花数”并输出。
“水仙花数”是指一个n位数,其各位数字的n次方之和确好等于该数本身,如:153=1^3+5^3+3^3,则153是一个“水仙花数”。
#include<stdio.h>
#include<math.h>
int main()
{
int i = 0;
for (i = 0;i < 100000;i++)
{
int count = 1;
int sum = 0;
int tmp = i;
//求数字的位数count
while (tmp / 10)
{
count++;
tmp = tmp / 10;
}
//计算每一位上数字的count次方的和
tmp = i;
while (tmp)
{
sum += pow(tmp % 10, count);
tmp = tmp / 10;
}
//判断
if (sum == i)
{
printf("%d\n", i);
}
}
return 0;
}
分析:
| 思路: | |
|---|---|
| 此题的关键在于只要知道判断一个数据是否为水仙花数的方式,问题就迎刃而解。假定给定一个数据data,具体检测方式如下: | |
| 1. 求取data是几位数 | |
| 2. 获取data中每个位置上的数据,并对其进行立方求和 | |
| 3. 对data中每个位上的数据立方求和完成后,在检测其结果是否与data相等即可, | |
| 相等:则为水仙花数 | |
| 否则:不是 |
这步不能漏掉!
因为要把改变过的tmp变回原来的值
十五.打印菱形
#include<stdio.h>
int main()
{
int line = 0;
scanf("%d", &line);
int i = 0;
//上三角
for (i = 0;i < line;i++)
{
//一行
int j = 0;
//打印空格
for (j = 0;j < line - 1 - i;j++)
{
printf(" ");
}
//打印*
for (j = 0;j < 2 * i + 1;j++)
{
printf("*");
}
printf("\n");
}
//下三角
for (i = 0;i < line - 1;i++)
{
int j = 0;
//打印空格
for (j = 0;j <= i;j++)
{
printf(" ");
}
//打印*
for (j = 0;j < 2 * (line - 1 - i) - 1;j++)
{
printf("*");
}
printf("\n");
}
return 0;
}
分析:
| 思路: | |
| 仔细观察图形,可以发现,此图形中是由空格和*按照不同个数的输出组成的。 | |
| 上三角:先输出空格,后输出*,每行中 | |
| 空格:从上往下,一行减少一个 | |
| *:2*i+1的方式递增 | |
| 下三角:先输出空格,后输出*,每行中 | |
| 空格:从上往下,每行多一个空格 | |
| *: 从上往下,按照2*(line-1-i)-1的方式减少,其中:line表示总共有多少行 | |
| 按照上述方式,将上三角和下三角中的空格和*分别输出即可。 | |
十六.喝汽水问题
喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水(编程实现)。
| 思路: | |
| 1. 20元首先可以喝20瓶,此时手中有20个空瓶子 | |
| **2. 两个空瓶子可以喝一瓶,喝完之后,空瓶子剩余:**empty/2(两个空瓶子换的喝完后产生的瓶子) + empty%2(不够换的瓶子) | |
| 3. 如果瓶子个数超过1个,可以继续换,即重复2 | |
#include<stdio.h>
int main()
{
int money = 0;
scanf("%d", &money);
int total = money;
int empty = money;
while (empty > 1)
{
total = total + empty / 2;
empty = empty / 2 + empty % 2;
}
printf("%d\n", total);
return 0;
}
方法二:按照上述喝水和用瓶子换的规则的话,可以发现,
其实就是个等差数列:money*2-1
十七.谁是凶手
日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。
以下为4个嫌疑犯的供词:
A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说
已知3个人说了真话,1个人说的是假话。
现在请根据这些信息,写一个程序来确定到底谁是凶手。
凶手无非4选1,这是一个人脑都可以做的遍历。那我们就模拟人脑遍历的思路来写程序就行了。我们设定凶手为1,不是凶手为0
#include<stdio.h>
int main()
{
int murder[4] = { 0 };//假设四个人都不是凶手
int i = 0;
for (i = 0;i < 4;i++)
{
murder[i] = 1;//假设这个人为凶手
if ((murder[0] != 1) +
(murder[2] == 1) +
(murder[3] == 1) +
(murder[3] != 1) == 3)//三句话为真,一句话为假
{
printf("the murder is %c\n", i +'A');
break;
}
else
{
murder[i] = 0;//不满足条件则这个人不是凶手
}
}
return 0;
}
写法二:
#include<stdio.h>
int main()
{
char killer = 0;
for (killer = 'A';killer <= 'D';killer++)
{
if ((killer != 'A') + (killer == 'C') + (killer == 'D') + (killer != 'D') == 3)
{
printf("%c", killer);
}
}
return 0;
}
十八.杨辉三角
在屏幕上打印杨辉三角。
1
1 1
1 2 1
1 3 3 1
……
#include<stdio.h>
void yangHuiTriangle(int n)
{
int arr[30][30] = { 1 };//先把第一行置为1
int i = 0;
int j = 0;
//存数据
for (i = 1;i < n;i++)
{
arr[i][0] = 1;//每行第一列都是1
for (j = 1;j <= i;j++)
{
arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
}
}
//打印数据
for (i = 0;i < n;i++)
{
for (j = 0;j <= i;j++)
{
printf("%-2d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int n = 0;
scanf("%d", &n);
yangHuiTriangle(n);
return 0;
}
分析:
由于此题要打印整个杨辉三角的数据而非取出某一项,所以不可避免的一定是要填出每一项,没有偷懒的余地,那就老老实实的根据规律填空即可。按照题设的场景,能发现数字规律为:
d[ i ][ j ] = d[i - 1][ j ] + d[i - 1][j - 1]。所以我们只要按照这个方法填表即可。
改进:
由于我在填第n行的杨辉三角时,只跟第n-1行的杨辉三角产生联系,不会跟之前的有联系,所以没必要保存每一行的杨辉三角,填一行打一行就行了,这样能让空间复杂度从n^2降低到n。但是在填数据的时候不能对之前的数据覆盖,所以需要从后向前填。而填杨辉三角顺序对结果是没有影响的,所以可以实现。
#include<stdio.h>
void yangHuiTriangle(int n)
{
int data[30] = { 1 };
int i, j;
printf("1\n"); //第一行就直接打印了
for (i = 1; i < n; i++) //从第二行开始
{
for (j = i; j > 0; j--) //从后向前填,避免上一行的数据在使用前就被覆盖
{
data[j] += data[j - 1]; //公式同上,由于变成了一维,公式也变简单了。
}
for (j = 0; j <= i; j++) //这一行填完就直接打印了。
{
printf("%d ", data[j]);
}
putchar('\n');
}
}
int main()
{
int n = 0;
scanf("%d", &n);
yangHuiTriangle(n);
return 0;
}
十九.字符串逆序
写一个函数,可以逆序一个字符串的内容。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
void Reverse(char* str)
{
char* left = str;
char* right = str + strlen(str) - 1;
char tmp;
while (left < right)
{
tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main()
{
char arr[10086] = { 0 };
scanf("%[^\n]", arr);
Reverse(arr);
int i = 0;
for (i = 0;i < strlen(arr);i++)
{
printf("%c", arr[i]);
}
return 0;
}
分析:
这道题的难点是如何输入一个中间有空格的字符串
因为我们知道 scanf 在遇到空格后便停止了,所以在这里我们要用到:
scanf("%[^\n]", arr);
这个的意思是在 '\n' (也就是回车) 之前 scanf 不会停止读取
或者我们也可以用 gets函数
#include<stdio.h>
#include<string.h>
void Reverse(char* str)
{
char* left = str;
char* right = str + strlen(str) - 1;
char tmp;
while (left < right)
{
tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main()
{
char arr[10086] = { 0 };
gets(arr);
Reverse(arr);
int i = 0;
for (i = 0;i < strlen(arr);i++)
{
printf("%c", arr[i]);
}
return 0;
}
二十.倒置字符串
将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I
#include<stdio.h>
#include<string.h>
#include<assert.h>
void Reverse(char* left, char* right)
{
assert(left&&right);
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main()
{
char arr[100] = { 0 };
//输入
gets(arr);
int len = strlen(arr);
//逆置
//先逆置单词,再逆置句子
char* start = arr;
char* end = start;
while (*end != '\0')
{
while (*end != ' '&&*end != '\0')
{
end++;
}
Reverse(start, end-1);//逆置这个单词
if (*end == '\0')
{
start = end;
}
else
{
start = end + 1;
}
end = start;
}
//逆置句子
Reverse(arr, arr + len - 1);
//输出
printf("%s", arr);
return 0;
}
思路是先找到这个句子中的单词,将单词逆序,然后再将整个句子逆序。
二十一.猜名次
5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:
A选手说:B第二,我第三;
B选手说:我第二,E第四;
C选手说:我第一,D第二;
D选手说:C最后,我第三;
E选手说:我第四,A第一;
比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。
#include<stdio.h>
int main()
{
int a, b, c, d, e;
for (a = 1;a <= 5;a++)
{
for (b = 1;b <= 5;b++)
{
for (c = 1;c <= 5;c++)
{
for (d = 1;d <= 5;d++)
{
for (e = 1;e <= 5;e++)
{
if ((b == 2) + (a == 3) == 1
&& ((b == 2) + (e == 4) == 1)
&& ((c == 1) + (d == 2) == 1)
&& ((c == 5) + (d == 3) == 1)
&& ((e == 4) + (a == 1) == 1))
{
if (a*b*c*d*e == 120)
{
printf("a=%d b=%d c=%d d=%d e=%d", a, b, c, d, e);
}
}
}
}
}
}
}
return 0;
}
二十二.小乐乐走台阶
小乐乐上课需要走n阶台阶,因为他腿比较长,所以每次可以选择走一阶或者走两阶,那么他一共有多少种走法
#include<stdio.h>
int fib(int n)
{
if (n <= 2)
{
return n;
}
else
return fib(n - 1) + fib(n - 2);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = fib(n);
printf("%d", ret);
return 0;
}
分析:我们总结规律发现:这貌似是一个斐波那契数列
二十三.小乐乐改数字
小乐乐喜欢数字,尤其喜欢0和1。他现在得到了一个数,想把每位的数变成0或1。如果某一位是奇数,就把它变成1,如果是偶数,那么就把它变成0。请你回答他最后得到的数是多少。
#include<stdio.h>
#include<math.h>
int main()
{
int n = 0;
int sum = 0;
int count = 0;
scanf("%d", &n);
while (n)
{
int ret = n % 10;
if (ret % 2 == 0)
{
ret = 0;
}
else
{
ret = 1;
}
sum += ret * pow(10, count);
count++;
n /= 10;
}
printf("%d", sum);
return 0;
}
二十四.调整数组使奇数全部都位于偶数前面。
题目:
输入一个整数数组,实现一个函数,
来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,
所有偶数位于数组的后半部分。
#include<stdio.h>
void print(int* arr, int sz)
{
int i = 0;
for (i = 0;i < sz;i++)
{
printf("%d ", arr[i]);
}
}
void Move(int* arr, int sz)
{
int* left = arr;
int* right = arr + sz - 1;
while (left < right)
{
//从左向右找,找到偶数就停止
while ((left < right) && (*left % 2 == 1))
{
left++;
}
//从右向左找,找到奇数就停止
while ((left < right) && (*right % 2 == 0))
{
right--;
}
if (left < right)
{
int tmp = *left;
*left = *right;
*right = tmp;
}
}
}
int main()
{
int arr[7] = { 15,14,22,48,17,19,21 };
int sz = sizeof(arr) / sizeof(arr[0]);
print(arr,sz);
printf("\n");
Move(arr, sz);
print(arr, sz);
return 0;
}
二十五. 2的n次方计算
不使用累计乘法的基础上,通过移位运算(<<)实现2的n次方的计算。
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int i = 2 << (n - 1);
printf("%d", i);
return 0;
}
二十六.空心三角形图案
#include<stdio.h>
int main()
{
int n = 0;
while (~scanf("%d", &n))
{
int i = 0;
int j = 0;
for (i = 0;i < n;i++)
{
for (j = 0;j <= i;j++)
{
if (j == 0 || i == j || i == n - 1)
{
printf("* ");
}
else
{
printf(" ");
}
}
printf("\n");
}
}
return 0;
}
二十七.带空格直角三角形图案
带空格直角三角形图案__牛客网 (nowcoder.com)
#include<stdio.h>
int main()
{
int n = 0;
while (scanf("%d",&n)!=EOF)
{
int i = 0;
int j = 0;
for (i = 1;i <= n;i++)
{
for (j = 1;j <= 2 * n - 2 * i;j++)
{
printf(" ");
}
for (j = 1;j <= i;j++)
{
printf("* ");
}
printf("\n");
}
}
return 0;
}
二十八.小乐乐排电梯
小乐乐排电梯__牛客网
小乐乐学校教学楼的电梯前排了很多人,他的前面有n个人在等电梯。电梯每次可以乘坐12人,每次上下需要的时间为4分钟(上需要2分钟,下需要2分钟)。请帮助小乐乐计算还需要多少分钟才能乘电梯到达楼上。(假设最初电梯在1层)
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int count = 0;//计时器
int tmp = n;
while (tmp / 12)
{
count += 4;
tmp -= 12;
}
count += 2;
printf("%d", count);
return 0;
}
二十九.矩阵转置
#include <stdio.h>
int main()
{
int n = 0;//行
int m = 0;//列
scanf("%d %d", &n, &m);
int arr[10][10] = { 0 };
for (int i = 0;i < n ;i++)
{
for (int j = 0;j < m;j++)
{
scanf("%d", &arr[i][j]);
}
}
for (int i = 0;i < m;i++)
{
for (int j =0;j < n;j++)
{
printf("%d ", arr[j][i]);
}
printf("\n");
}
return 0;
}
三十.序列中删除指定数字
序列中删除指定数字_牛客题霸_牛客网 (nowcoder.com)
有一个整数序列(可能有重复的整数),现删除指定的某一个整数,输出删除指定数字之后的序列,序列中未被删除数字的前后位置没有发生改变
思路一:开辟一个辅助数组, 把不需要删除的数放到这个辅助数组中
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int arr[50] = { 0 };
int arr2[50] = { 0 };
int i = 0;
int j = 0;
int count = 0;
int c = 0;
for (i = 0;i < n;i++)
{
scanf("%d", &arr[i]);
}
int k = 0;
scanf("%d", &k);
for (i = 0;i < n;i++)
{
if (k == arr[i])
{
c++;
}
else
arr2[count++] = arr[i];
}
for (i = 0;i < count;i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
思路一的局限性:由于是开辟了一个辅助数组,所以并没有真正意义上地把需要删除的数从数组中删除
思路二:真正意义上地将这个元素从数组中删除
#include<stdio.h>
int main()
{
int n=0;
int arr[50]={0};
scanf("%d",&n);
int i=0;
int j=0;
for(i=0;i<n;i++)
{
scanf("%d",&arr[i]);
}
int del=0;
scanf("%d",&del);
for(i=0;i<n;i++)
{
if(arr[i]!=del)
{
arr[j++]=arr[i];
}
}
//输出
for(i=0;i<j;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
三十一.一元二次方程
我们都学过解一元二次方程,今天我们试着用编程实现一个二元一次方程的求解
计算一元二次方程_牛客题霸_牛客网 (nowcoder.com)
这题看着复杂,实际不难,只要有耐心按要求写下去就行
#include<stdio.h>
#include<math.h>
int main()
{
float a, b, c = 0;
float x1, x2 = 0;
float r,i = 0;
while (~scanf("%f %f %f", &a, &b, &c))//a,b,c表示一元二次方程的系数
{
float d = b * b - 4 * a*c;//根的判别式
x1 = (-b - sqrt(d))*1.0 / (2 * a);
x2 = (-b + sqrt(d))*1.0 / (2 * a);
if (a != 0)
{
if (d == 0)//两个实根相等
{
printf("x1=x2=%.2f", x2);
}
else if (d > 0)//两个实根不相等
{
printf("x1=%.2f;x2=%.2f", x1, x2);
}
else//有两个虚根
{
r = -b * 1.0 / (2 * a);
i = sqrt(-d)*1.0 / (2 * a);
printf("x1=%.2f-%.2fi;x2=%.2f+%.2fi",r,i,r,i);
}
}
else
{
printf("Not quadratic equation");
}
printf("\n");
}
return 0;
}
三十二.变种水仙花数
变种水仙花数 - Lily Number:把任意的数字,从中间拆分成两个数字
比如1461 可以拆分成(1和461),(14和61),(146和1)
如果所有拆分后的乘积之和等于自身, 则是一个Lily Number。
版本1:比较直接,但有些笨
#include<stdio.h>
int main()
{
long i=0;
for(i=10000;i<100000;i++)
{
long a1=i/10000;
long a2=i%10000;
int b1=i/1000;
int b2=i%1000;
int c1=i/100;
int c2=i%100;
int d1=i/10;
int d2=i%10;
if(a1*a2+b1*b2+c1*c2+d1*d2==i)
{
printf("%d ",i);
}
}
return 0;
}
版本2:在版本1的基础上做了一些优化
#include<stdio.h>
#include<math.h>
int main()
{
for(int i=10000;i<100000;i++)
{
int sum=0;
int tmp=i;
int mod=10000;
while(mod/10)
{
sum+=(tmp/mod)*(tmp%mod);
mod/=10;//更新mod
}
if(i==sum)
{
printf("%d ",i);
}
}
return 0;
}
三十三.进制A+B
输入一个十六进制数a,和一个八进制数b,输出a+b的十进制结果
#include<stdio.h>
int main()
{
int a=0;
int b=0;
scanf("%x %o",&a,&b);
printf("%d\n",a+b);
return 0;
}
这道题的关键就是要知道
十六进制Hexadecimal一般以0x开头,例如0xFF。八进制Octal,一般以0开头,例如07。
问题是如何读入对应的进制数 --> %x %o分别可以用于读入十六进制和八进制
三十四.X型图案
#include<stdio.h>
int main()
{
int n=0;
while(~scanf("%d",&n))
{
int i=0;
int j=0;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(j==i)
{
printf("*");
}
else if(j==n-i-1)
{
printf("*");
}
else
{
printf(" ");
}
}
printf("\n");
}
}
return 0;
}
分析:
X形图案可以拆分成两根斜线
其中i==j时输出星号,或者i==n-i-1时输出星号即可,其他情况皆输出空格。
三十五.有序序列插入一个数
有序序列插入一个数_牛客题霸_牛客网 (nowcoder.com)
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int i = 0;
int flag=0;
int arr[20] = { 0 };
for (i = 0;i < n;i++)
{
scanf("%d", &arr[i]);
}
int k = 0;
scanf("%d", &k);
int index = 0;
for (i = 0;i < n;i++)
{
if (k < arr[i])
{
index = i;
flag=1;
break;
}
}
if (i == n - 1)
{
index = n - 1;
}
//插入
if(flag==0)
{
arr[n]=k;
}
else
{
for (i = n;i >=index;i--)
{
arr[i + 1] = arr[i];
}
arr[index] = k;
}
for (i = 0;i < n + 1;i++)
{
printf("%d ", arr[i]);
}
return 0;
}
三十六.回文的判断
所谓回文,就是去掉空格之后的字符串是中心对称的
#include<stdio.h>
#include<string.h>
int Palindrome(char* s)
{
int len = strlen(s);
char* left = s;
char* right = s + len - 1;
while (left < right)
{
while (*left == ' ')
{
left++;
}
while (*right == ' ')
{
right--;
}
if (*left == *right)
{
left++;
right--;
}
else
{
return 0;
}
}
return 1;
}
int main()
{
char str[50] = { 0 };
while (~gets(str))
{
if (Palindrome(str))
{
printf("It is a Palindrome\n");
}
else
{
printf("It is not a Palindrome\n");
}
}
return 0;
}
三十七. 统计单词出现的个数
找出给定单词在一段文字中出现的次数,假定原文中的任意分割符均不会连续出现
#include<stdio.h>
#include<assert.h>
#include<string.h>
int search(const char* str, const char* key)
{
assert(str&&key);
int count = 0;
char dest[20] = { 0 };//存储句子中的一个单词
while (*str)
{
int i = 0;
while ((*str >= 'a'&& *str <= 'z') || (*str >= 'A'&& *str <= 'Z'))
{
dest[i++] = *str++;
}
dest[i] = '\0';//单词结束后加结尾标志
str++;//指向句子的下一个单词
if (strcmp(dest, key) == 0)//比较得到的单词与想查找的单词是否相同
{
count++;
}
}
return count;
}
int main()
{
char str[100] = { 0 };
printf("Please input the sentence\n");
gets(str);
char key[20] = { 0 };
printf("Please input the key world\n");
gets(key);
printf("There are %d key words in this sentence\n", search(str, key));
return 0;
}
三十八.密码问题
要求用户输入密码,以‘#’作为结束标志
//密码问题
#include<stdio.h>
char password[] = "NJUPT";//设定的密码
int check(char* str)
{
int i = 0;
int flag = 1;
for (;*str != '\0'&&flag;str++)
{
if (*str >= 'a'&& *str <= 'z')
{
*str = *str - 32;
}
if (*str != password[i])
{
flag = 0;
}
else
{
i++;
}
}
return flag;
}
int main()
{
char str[20] = { 0 };
printf("Please input your password\n");
int i = 0;
while ( ( *(str+i)=getchar() )!='#')
{
i++;
}
*(str + i) = '\0';
if (check(str))
{
printf("Pass!\n");
}
else
{
printf("Reeor!\n");
}
return 0;
}