PTA L1系列题解(C语言)(L1_009 -- L1_016)

L1-009 N个数求和

题目内容:

解题思路:

整体思路,对于每两个分数相加,要先通分,但为了解题简便起见,我们直接将两个分母相乘,分子乘以对向分母再相加,得到一个新的分数,然后再进行约分。

        第一步,两个分数相加,然后求出新分数的分子分母的最大公约数,求出新分数的最简形式。

        第二步,将分数改成答案要求的格式,总共分三种情况,能除尽的,分子小于分母的,有整数有分数的。

C代码展示:

#include <stdio.h>

// 递归实现的欧几里得算法计算最大公约数
long long gcd(long long a, long long b)
{
    return b ? gcd(b, a % b) : a;
}

// 迭代实现的欧几里得算法计算最大公约数
long long gcd_1(long long a, long long b)
{
    long long r = 0;
    while (b != 0) {
        r = a % b;
        a = b;
        b = r;
    }
    return a;
}

int main()
{
    int n;
    long long sum_a, sum_b, ans_a, ans_b, _ans;

    scanf("%d", &n);

    scanf("%lld/%lld", &sum_a, &sum_b); // 读取第一个分数
    for (int i = 0; i < n - 1; i++) {
        long long a, b, temp; // 定义临时变量,用于存储当前分数的分子和分母
        scanf("%lld/%lld", &a, &b); // 读取下一个分数
        sum_a = sum_a * b + sum_b * a; // 根据分数加法规则计算新的分子
        sum_b = sum_b * b; // 计算新的分母
        temp = gcd_1(sum_a, sum_b); // 计算新分数的最大公约数
        sum_a = sum_a / temp; // 简化分数
        sum_b = sum_b / temp; // 简化分数
    }
    _ans = sum_a / sum_b; // 计算最终结果的整数部分
    ans_a = sum_a % sum_b; // 计算最终结果的小数部分的分子
    ans_b = sum_b; // 计算最终结果的小数部分的分母
    if (ans_a == 0) {
        printf("%lld\n", _ans); // 如果小数部分的分子为0,则只输出整数部分
    } else {
        if (_ans == 0) {
            printf("%lld/%lld\n", ans_a, ans_b); // 如果整数部分为0,则只输出小数部分
        } else {
            printf("%lld %lld/%lld\n", _ans, ans_a, ans_b); // 否则,输出整数部分和小数部分
        }
    }

    return 0;
}

L1-010 比较大小

题目内容:

解题思路:

方法一:使用排序算法将它先进行排序。

方法二:可以利用题目特殊性,将最大值和最小值找出来,然后三数之和减掉另外两个数。

C代码展示:

//方法一(冒泡排序)
#include <stdio.h>

int main()
{
	int s[5] = {0}, temp=0;
	scanf("%d %d %d", &s[0], &s[1], &s[2]);
	for (int i=0; i<3; i++){
		for (int j=0; j<2; j++){
			if (s[j] > s[j+1]){
				temp = s[j];
				s[j] = s[j+1];
				s[j+1] = temp;
			}
		}
	}
	for (int i=0; i<2; i++) printf("%d->", s[i]);
	printf("%d\n", s[2]);
	return 0;
}
//方法二
#include <stdio.h>

int main()
{
	int a, b, c, max, min, mid;
	scanf("%d %d %d", &a, &b, &c);
	max = a>(b>c ? b : c) ? a : (b>c ? b : c);
	min = a<(b<c ? b : c) ? a : (b<c ? b : c);
	mid = a + b + c - max - min;
	printf("%d->%d->%d\n", min, mid, max);
	
	return 0;
}

L1-011 A-B

题目内容:

解题思路:

为了缩短运行时间,可以采用哈希表记录,在录入B字符串的时候,标记B字符串中出现的字符,在后续判断A字符串时可以直接查找哈希表。

C代码展示:

#include <stdio.h>
#include <string.h>

int main() {
    char s[10005];
    char _s[10005];
    int hash[500]; // 定义一个整数数组hash,用于存储字符是否出现过的标志

    gets(s);
    gets(_s);

    for (int i = 0; i < strlen(_s); i++) { // 遍历字符串_s中的每个字符
        hash[(int) _s[i]] = 1; // 将_s中出现的字符在hash数组中对应的位置标记为1
    }

    for (int i = 0; i < strlen(s); i++) { // 遍历字符串s中的每个字符
        if (hash[(int) s[i]] == 0) { // 如果s中的字符在hash数组中对应的位置为0,即没有在_s中出现过
            printf("%c", s[i]); // 则输出这个字符
        }
    }
    printf("\n");

    return 0;
}

L1-012 计算指数

题目内容:

解题思路:

注意:pow函数返回值为浮点型。

C代码展示:

#include <stdio.h>
#include <math.h>

int main()
{
	int n;
	scanf("%d", &n);
	printf("2^%d = %.0f\n", n, pow(2, n));
	
	return 0;
}

L1-013 计算阶乘和

题目内容:

解题思路:

略。

C代码展示:

#include <stdio.h>

int main()
{
	int n, sum=0, temp=1;
	scanf("%d", &n);
	
	for (int i=1; i<=n; i++){
		for (int j=1; j<=i; j++){
			temp *= j;
		}
		sum += temp;
		temp = 1;
	}
	printf("%d\n", sum);
	
	return 0;
}

L1-014 简单题

题目内容:

解题思路:

略。

C代码展示:

#include <stdio.h>

int main()
{
    printf("This is a simple problem.\n");
    return 0;
}

L1-015 跟奥巴马一起画方块

题目内容:

解题思路:

对于行数,由于N为整数,所以:

实际行数 = (N+1) / 2

C代码展示:

#include <stdio.h>

int main()
{
	int n;
	char c;
	scanf("%d %c", &n, &c);
	for (int i=0; i<(n+1)/2; i++){
		for (int j=0; j<n; j++){
			printf("%c", c);
		}
		printf("\n");
	}
	
    return 0;
}

L1-016 查验身份证

题目内容:

解题思路:

注意点1:输入时有字符,所以应该设置字符数组。

注意点2:错误身份证号可以分两种方式判断,一是前17位有字符,二是前17位算出的校验值与18位的校验位不同。

注意点3:当全部身份证号都是正确时,输出“All passed”,可以定义一个标记量k,当有错误身份证号时自增,最后判断k的值。

C代码展示:

#include <stdio.h> 

int main() {
    int q[17] = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
     // 定义权重数组
    char m[11] = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
     // 定义校验码对应数组
    int n, sum = 0, k = 0, flag = 1; 
    // 定义变量n(身份证号码数量),sum(权重和),k(错误计数),flag(校验标志)
    char a[20];

    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%s", a);
        sum = 0; // 初始化权重和为0
        flag = 1; // 初始化校验标志为1
        for (int j = 0; j < 17; j++) {
            if ('0' <= a[j] && a[j] <= '9') {
                sum += (a[j] - '0') * q[j]; // 计算权重和
            } else {
                flag = 0; // 如果出现非数字字符,设置校验标志为0
                break; // 跳出循环
            }
        }
        if (flag == 1) { // 如果校验标志为1,说明前17位都是数字
            if (m[sum % 11] != a[17]) { // 计算校验码,并与身份证号码的最后一位比较
                k++; // 如果校验码不匹配,错误计数加1
                flag = 0; // 设置校验标志为0
            }
        }
        if (flag == 0) { // 如果校验标志为0,输出错误身份证号码
            printf("%s\n", a);
        }
    }
    if (k == 0) { // 如果错误计数为0,说明所有身份证号码都通过了校验
        printf("All passed\n");
    }

    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值