实验二解答.md

实验二解答

第一关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<stdio.h>
#define PI 3.14159
int main(){
int f;
short p, k;
double c, r, s;

/*任务1*/
printf("Input Fahrenheit:");
scanf("%d", &f);
c=5.0/9.0*(f-32.0); //注:把里面常量都变成double防位数丢失
printf("\n %d(F)=%.2f(C)\n\n",f,c);
/*任务2*/
printf("input the radius r:");
scanf("%lf",&r); //注:输入double用%lf
s = r*r*PI;
printf("\nThe acreage is %.2lf\n\n",s);
/*任务3*/
k=0xa1b2, p=0x8423;
int newint = (p&0xff00) | (k&0xff00)>>8; //注意优先级
printf("new int = %x\n\n",newint); //注:去掉#,等于去前缀0x
return 0;
}

第二关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
int main(){
int a;
scanf("%d",&a);
int b = a; //拷贝原数字
int i = 0; //标记位数
int sum = 0;
while(b!=0){
sum += b%10;
b = b/10;
i++;
}
printf("%d是%d位数,且各位数字之和为%d。",a,i,sum);
}

第三关

比较简单粗暴的比较前后趋势

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<stdio.h>
int main(){
int count;
scanf("%d",&count);
if(count<=2) {
printf("0");
return 0;
}
int result=0;
int a,b;
int trend;
scanf("%d%d",&a,&b); //初始输入两个数
trend = b>=a?1:0; //判断第一个趋势
for(int i=2;i<count;i++){
a=b;
scanf("%d",&b);
if(trend!=b>=a?1:0){ //判断趋势是否变化
trend=b>=a?1:0;
result++;
}
}
printf("%d",result);
}

第四关

简单粗暴的if

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<stdio.h>
#include<string.h>
#include<ctype.h>
void main(){
char input[20];
fgets(input,20,stdin);
input[strcspn(input,"\n")]=0;
if(strlen(input)!=11){
printf("长度不合法");
return;
}
for(int i=0;i<strlen(input);i++){
if(!isdigit(input[i])){
printf("字符串中存在非数字字符");
return;
}
}
if(input[0]!='1'){
printf("第1位不合法");
return;
}
if(input[1]<'3'){
printf("第2位不合法");
return;
}
}

第五关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 #include <stdio.h>
int main() {
// 基本输入和判断数据是否有误
unsigned short x, m, n;
scanf("%hx %hu %hu", &x, &m, &n);
if(m<0 || m>15 || n<1 || n>16-m){
return 0;
}
// 构建掩码
unsigned short mask = (1 << n) - 1;//先得到n个1
mask <<= m;//然后把这段1移动到正确位置

unsigned short bits = (x & mask);// 用掩码截取指定位置
unsigned short result = bits << (16 - n-m);//对齐左端
printf("%hx\n", result);//以十六进制打印
return 0;
}

第六关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
#include<string.h>
void main(){
// 循环输入(假)
unsigned long IP[1024]={0};// 给个默认值方便判断出口
for(int i=0;i<1024;i++){
scanf("%ld",IP+i);
}
// 简单粗暴地截取拼接
for(int i=0;i<1024;i++){
if(IP[i]==0)return;
printf("%d.%d.%d.%d\n",(IP[i]&0xff000000)>>24,(IP[i]&0xff0000)>>16,(IP[i]&0xff00)>>8,IP[i]&0xff);
}
}

第七关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 #include<stdio.h>
#include<string.h>
#include<ctype.h>

void main(){
// 输入一行
char input[1024];
fgets(input,1024,stdin);
input[strcspn(input,"\n")]=0;
// 加密
int add;
scanf("%d",&add);
for(int i=0;i<strlen(input);i++){
if(isupper(input[i])){
// 由于ascii码中字母是连着的,直接加
input[i] = input[i] + add-1;
// 超过范围就循环回去
if(input[i]>'Z'){
input[i] = input[i] - 26;
}
}
}
// 两两交换,每两个字符一组进行互换,显然,剩下单字符时i将会大于input长度,循环终止
for(int i=0;i<strlen(input);i+=2){
char temp = input[i];
input[i] = input[i+1];
input[i+1] = temp;
}
printf("%s",input);
}

第八关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <stdio.h>  
#include <string.h>
// 判断一段字节是否是中文
int isChinese(const char *s) {
if (s == NULL || *s == '\0') {
return 0;
}
unsigned char c = (unsigned char)*s;
if ((c >= 0xE4 && c <= 0xE9) || (c >= 0xF0 && c <= 0xF7)) {
return 1;
}
return 0;
}

int main() {
int line = 0;
int word = 0;
int c = 0;
char buffer[1024];
char *token;
// 循环输入
while (fgets(buffer, 1024, stdin) != NULL) {
char *pos = buffer;
for(int i=0;i<strlen(buffer);i++){
if(buffer[i]=='\t' || buffer[i]=='\n'){
buffer[i]=' ';
}
}
// 由于题目中一个"字"(题目中应指由空格分隔的一个词)应该要么由中文组成,要么由英文组成,以空格为分隔符进行切割
token = strtok(buffer, " ");

while (token != NULL) {
int len = strlen(token);
// 一个中文3字节,若是一个"字"有3个以上字节则可能是中文,运行isChinese函数进一步判断
if (len >= 3 && isChinese(token)) {
// 是纯中文"字",根据中文特点进行计数
word += len/3;
c += len/3;

} else {
// 不是中文,根据英文特点进行计数
word += (len > 0) ? 1 : 0;
c += len;
}
// 切割下一个,while循环条件即判断是否还能切割到"字"
token = strtok(NULL," ");
}
line++;
}
// 打印输出
printf("字数 %d\n", word);
printf("字符数 %d\n", c);
printf("行数 %d", line);

return 0;
}

第九关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>  
#include <string.h>

int main() {
// 输入一行
char buffer[1024];
fgets(buffer,1024,stdin);
buffer[strcspn(buffer,"\n")]=0;

char newstr[strlen(buffer)];// 存储新字符串
for(int i=0;i<strlen(buffer);i++){
unsigned char c = buffer[i];
unsigned char newc = 0;
// 比较愚蠢的交换,可以用for来写
newc |= ((c & (1 << 0)) >> 0) << 1;
newc |= ((c & (1 << 1)) >> 1) << 0;
newc |= ((c & (1 << 2)) >> 2) << 3;
newc |= ((c & (1 << 3)) >> 3) << 2;
newc |= ((c & (1 << 4)) >> 4) << 5;
newc |= ((c & (1 << 5)) >> 5) << 4;
newc |= (c & (3 << 6));
// 根据6,7位计算移动位数
int shift = (c >> 6) & 3;
unsigned char low_bits = newc & 0x3F; // 把低6位拿出来循环左移
low_bits = (low_bits << shift) | (low_bits >> (6 - shift));
// 拼接高2位和循环左移后的低6位
newc = (newc & 0xC0) | low_bits;
newstr[i] = newc;
}
// 安全措施,保证最后一个字符是'\0',可以去掉
newstr[strlen(buffer)]='\0';
printf("%s",newstr);
}

实验二解答.md
https://fiy-pc.github.io/2024/10/31/实验二解答-md/
作者
FIY-pc
发布于
2024年10月31日
许可协议