第二次作业 数据类型、运算符和表达式

发布时间 2023-10-14 23:00:21作者: 计算概论B-2023秋-4班
  1. 求一元二次方程的根

注意\(\dfrac{-b+\sqrt{b^2-4ac}}{2a}\)不一定比\(\dfrac{-b-\sqrt{b^2-4ac}}{2a}\)大。

#include <stdio.h>
#include <math.h>
int main() {
    float a, b, c;
    scanf("%f%f%f", &a, &b, &c);
    float d = b * b - 4 * a * c;
    if(d > 0) {
        float x1 = (-b + sqrt(d))/(2 * a);
        float x2 = (-b - sqrt(d))/(2 * a);
        if(x1 <= x2)
            printf("x1=%.5f;x2=%.5f", x2, x1);
        else
            printf("x1=%.5f;x2=%.5f", x1, x2);
    }
    else if(d == 0) {
        float x1 = (-b + sqrt(d))/(2 * a);
        printf("x1=x2=%.5f", x1);
    }
    else {
        printf("no solution");
    }
    return 0;
}
  1. Fibonacci数列

结果可能会比较大导致溢出。由于\((a\%m+b\%m)\%m=(a+b)\%m\),所以可以在计算过程中进行取余,得到的结果仍然是正确的。

(设\(a=k_1m+c_1, b=k_2mc_2\),则\((a\%m+b\%m)\%m=(c_1+c_2)\%m, (a+b)\%m=((k_1+k_2)m+c_1+c_2)\%m=(c_1+c_2)\%m\))

同理,减法和乘法也有相同的规律,可自行证明。

#include <stdio.h>
int main() {
    int a, x = 0, y = 1, z;
    scanf("%d", &a);
    for(int i = 1; i < a; i++) {
        z = x + y;
        x = y;
        y = z % 10000;
    }
    printf("%d", y);
	return 0;
}
  1. 二进制加法

由于输入最长有100位,而最长的整型long long只有64个二进制位,因此直接使用整型进行运算是行不通的,需要直接使用数组模拟竖式加法进行运算。

注意在进行相加时,最好先将最低位进行对齐方便操作。同时,由于运算之后可能有位数变化,因此将最低位存在编号较小的一段会比较方便。

#include <stdio.h>
#include <string.h>
int main() {
    int n;
    char str1[110], str2[110];
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        // 将两个数组清空
        memset(str1, 0, sizeof(str1));
        memset(str2, 0, sizeof(str2));
        // 输入两个字符串,注意变量名前不用加&
        scanf("%s%s", str1, str2);
        // 使用strlen函数直接得到字符串的长度
        int len1 = strlen(str1);
        int len2 = strlen(str2);
        // 反转两个字符串,对齐最低位
        for(int i = 0; i < len1 - i - 1; i++) {
            char temp;
            temp = str1[i];
            str1[i] = str1[len1 - i - 1];
            str1[len1 - i - 1] = temp;
        }
        for(int i = 0; i < len2 - i - 1; i++) {
            char temp;
            temp = str2[i];
            str2[i] = str2[len2 - i - 1];
            str2[len2 - i - 1] = temp;
        }
        // 将字符串中的字符'0'和'1'转为0和1
        // '1'的ascii码为49,减去'0'得到1,而'0'减去'0'显然得到的是0
        for(int i = 0; i < len1; i++) 
            str1[i] -= '0';
        for(int i = 0; i < len2; i++)
            str2[i] -= '0';
        // 将两个数字逐位相加并处理进位
        for(int i = 0; i < len1 || i < len2; i++) {
            str1[i] += str2[i];
            if(str1[i] >= 2) {
                str1[i+1] ++;
                str1[i] -= 2;
            }
        }
        // 得到最高位的位置并输出
        int x = len1;
        if(len2 > x)
            x = len2;
        if(str1[x])
            x++;
        while(x) {
            x--;
            printf("%d", str1[x]);
        }
        printf("\n");
    }
}