2021-2022CSU期末考试二
作者:互联网
题目如下:
1.格式转换
#include <stdio.h>
int main(void)
{
int h, p, m, d, y;
while (~scanf("%d:%d,%d/%d/%d", &h, &p, &m, &d, &y))
{
printf("%04d%02d%02d,", y, m, d);
if (h >= 12)
printf("%02d:%02dPM\n", (h == 12) ? 0 : h-12, p);
else
printf("%02d:%02dAM\n", h, p);
}
return 0;
}
2.描绘闪电
#include <stdio.h>
int main(void)
{
int n;
while (~scanf("%d", &n))
{
for (int i = 0; i < n; i++)
{
for (int j = 1; j <= n - i; j++)
{
printf(" ");
}
printf("*");
printf("\n");
}//打印第一段
for (int i = 1; i <= n + 1; i++)
printf("*");
printf("\n");//打印第二段
for (int i = 0; i < n; i++)
{
for (int j = n - i-1; j >= 1; j--)
printf(" ");
printf("*\n");
}//打印第三段
printf("\n");
}
return 0;
}
拆分成三段来打印
3.密码设置
#include<stdio.h>
#include<string.h>
int main(void)
{
char s[35];
while (~scanf("%s", s))
{
int len = strlen(s), sz = 0, xx = 0, dx = 0, ts = 0, flag = 0,flag2=1;
if (len < 8)
{
printf("no\n");
continue;
}
else//首先需要长度大于等于8,才能继续判断具体字符
{
for (int i = 0; i < len; i++)
{
int e = 1;//e记录是否有题目范围外的其他字符
if (s[i] >= '0' && s[i] <= '9')//判断数字
sz = 1,e=0;
if (s[i] >= 'a' && s[i] <= 'z')//判断小写字母
xx = 1,e=0;
if (s[i] >= 'A' && s[i] <= 'Z')//判断大写字母
dx = 1,e = 0;
if (s[i] == '!' || s[i] == '@' || s[i] == '#' || s[i] == '$' || s[i] == '*' || s[i] == '~')//判断特殊字符
ts = 1, e = 0;
if (e == 1)
{
flag2 = 0;
printf("no\n");
break;
}
}
if (flag2)
{
flag = sz + xx + dx + ts;
if (flag >= 3)//判断是否满足要求中至少三项
printf("yes\n");
else
printf("no\n");
}
}
}
return 0;
}
4.伪素数列
#include<stdio.h>
int isprime(int x)
{
if (x <= 1)
return 0;
else
{
for (int i = 2; i * i <= x; i++)
{
if (x % i == 0)
return 0;
}
return 1;
}
}
int main(void)
{
int a[5005] = { 0 };
int cnt = 0;
for (int i = 2; cnt <= 5000; i++)
{
if (isprime(i))
a[cnt++] = i;
else
{
int flag = 0;
int j = i;
while (j>0&&isprime(j%10))
{
j = j / 10;
}
if (j == 0)
a[cnt++] = i;
}
}
int x;
while (~scanf("%d", &x))
{
printf("%d\n", a[x - 1]);
}
return 0;
}
注意应尽量使代码简洁,不然会增加时间复杂度。
(我写这类题目经常时间超限...)
5.实数相加
本题思路:将两个实数拆分成整数部分和小数部分分别相加
这题有很多易错点(也可能是我的代码比较繁琐),具体的坑都在下面的代码中有标明。
#include <stdio.h>
#include<string.h>
int main(void)
{
char x[405] = { 0 }, y[405] = { 0 };
while (~scanf("%s %s", x, y))//用字符串的方式读入两个实数X和Y
{
int l1 = strlen(x), l2 = strlen(y);
char x1[405] = { 0 }, x2[405] = { 0 };//x1是第一个数的整数部分,x2是第一个数的小数部分
int i=l1, j=l2;//注意i与j的赋值不能为0,若找不到小数点那么整数部分长度就是l1与l2
for (int k = 0; k < l1; k++)
{
if (x[k] == '.')
{
i = k;//找到小数点,就是整数和小数部分分割的位置
}
}
for (int k = 0; k < i; k++)
{
x1[k] = x[k];
}
for (int k = i + 1; k < l1; k++)
{
x2[k-i-1] = x[k];
}//分割x
char y1[405] = { 0 }, y2[405] = { 0 };
for (int k = 0; k < l2; k++)
{
if (y[k] == '.')
{
j = k;
}
}
for (int k = 0; k < j; k++)
{
y1[k] = y[k];
}
for (int k = j + 1; k < l2; k++)
{
y2[k - j - 1] = y[k];
}//分割y
int r1[405] = { 0 }, t=0;//r1为储存整数最终结果的数组
int p = i - 1, q = j - 1;
int r2[405] = { 0 }, t2 = 0;//r2为储存小数最终结果的数组
//因为最终小数部分相加后可能会向整数部分进位,所以先计算小数部分
int len;
if (l1 - i > l2 - j)//len的长度应为两者中较长者
len = l1 - 1 - i-1;
else
len = l2 - 1 - j-1;
while (len >= 0)
{
int g=x2[len], r=y2[len];
//因为数组中原本储存的是数字0,所以此处应将其转换为字符0才能进行下面的转换
if (x2[len] == 0)
g = '0';
if (y2[len] == 0)
r = '0';
r2[t2] = r2[t2]+g - '0' + r - '0';
if (r2[t2] >= 10)
{
r2[t2] %= 10;
r2[t2 + 1]++;
}
t2++,len--;
}
if (r2[t2] != 0)//向整数部分进位
{
r1[0] = r1[0] + 1;
}
while (p >= 0 && q >= 0)
{
r1[t] = r1[t] + x1[p] - '0' + y1[q] - '0';
if (r1[t] >= 10)
{
r1[t] = r1[t] % 10;
r1[t + 1]++;
}
t++, p--, q--;
}
//计算多出来的部分
while (p >= 0)
{
r1[t] = r1[t] + x1[p] - '0';
t++, p--;
}
while (q >= 0)
{
r1[t] = r1[t] + y1[q] - '0';
t++, q--;
}//至此整数部分加好
if (r1[t] == 0)//判断整数部分的长度
t = t - 1;
for (t; t >= 0; t--)
printf("%d", r1[t]);//输出整数部分
int fir = 0;
while (r2[fir] == 0&&fir<t2)//找到最后一个不为0的小数
fir++;
if (fir != t2)
{
printf(".");
int j = t2 - 1;
for (j; j >= fir; j--)
printf("%d", r2[j]);
}
printf("\n");
}
return 0;
}
6.谍影寻踪
本题思路:指针的基本操作(前插、后插)+结构体
当时写这题的时候没有注意到可能两个人都是曾经出现过的,所以后面的判断重合部分又加了che指针检查是否两者都是出现过的,幸好最后没有时间超限,不知道能不能有大佬提供更简单的解法。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
int n;
while (~scanf("%d", &n))
{
struct node
{
int num;
int cnt = 1;
int n1;
int n2;
struct node* next;
};
struct node* head = NULL;
struct node* A = (struct node*)malloc(sizeof(struct node));
struct node* B = (struct node*)malloc(sizeof(struct node));
scanf("%d,%d->%d,%d", &(A->num), &(A->n1), &(B->num), &(B->n1));
B->next = head;
A->next = B;
head = A;
for (int i = 1; i <= n - 1; i++)
{
A = (struct node*)malloc(sizeof(struct node));
B = (struct node*)malloc(sizeof(struct node));
scanf("%d,%d->%d,%d", &(A->num), &(A->n1), &(B->num), &(B->n1));
B->next = NULL;
A->next = B;
struct node * cur = head,*pre=NULL;
while ((cur->num) != A->num && (cur->num) != B->num)
pre = cur, cur = cur->next;
if (cur->num == A->num)
{
int flag = 1;
struct node* che = head;
for (; che->next != NULL; che = che->next)
{
if (che->num == B->num)
{
flag = 0;
break;
}
}
if (che->num == B->num)
{
flag = 0;
}
if (flag)
{
B->next = cur->next;
cur->next = B;
}
else
{
if (che->n1 != B->n1)
{
che->cnt = 2;
che->n2 = B->n1;
}
}
if (cur->n1 != A->n1)
{
cur->cnt = 2;
cur->n2 = A->n1;
}
}
if (cur->num == B->num)
{
int flag = 1;
struct node* che = head;
for (; che->next != NULL; che = che->next)
{
if (che->num == A->num)
{
flag = 0;
break;
}
}
if (che->num == A->num)
{
flag = 0;
}
if (flag)
{
if (cur == head)
{
A->next = cur;
head = A;
}
else
{
pre->next = A;
A->next = cur;
}
}
else
{
if (che->n1 != A->n1)
{
che->cnt = 2;
che->n2 = A->n1;
}
}
if (cur->n1 != B->n1)
{
cur->cnt = 2;
cur->n2 = B->n1;
}
}
}
struct node* p = head;
while (p->next != NULL)
{
if (p->cnt == 2)
{
printf("%d,%d#%d->", p->num, p->n1, p->n2);
}
else
{
printf("%d,%d->", p->num, p->n1);
}
p = p->next;
}
if (p->cnt == 2)
{
printf("%d,%d#%d", p->num, p->n1, p->n2);
}
else
{
printf("%d,%d", p->num, p->n1);
}
printf("\n");
}
return 0;
}
以上仅个人的一点浅薄的看法,这是一学期来第一次考试满分,希望能对大家有帮助。如果有更好的解法,欢迎批评指正。
标签:cur,int,期末考试,num,2021,2022CSU,printf,n1,che 来源: https://blog.csdn.net/VeegeeScarf/article/details/122561908