注意\(\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;
}
结果可能会比较大导致溢出。由于\((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;
}
由于输入最长有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");
}
}