If a machine can save only 3 significant digits, the float numbers 12300 and 12358.9 are considered equal since they are both saved as 0.123*105 with simple chopping. Now given the number of significant digits on a machine and two float numbers, you are supposed to tell if they are treated equal in that machine.
Input Specification:
Each input file contains one test case which gives three numbers N, A and B, where N (<100) is the number of significant digits, and A and B are the two float numbers to be compared. Each float number is non-negative, no greater than 10100, and that its total digit number is less than 100.
Output Specification:
For each test case, print in a line “YES” if the two numbers are treated equal, and then the number in the standard form “0.d1…dN*10^k” (d1>0 unless the number is 0); or “NO” if they are not treated equal, and then the two numbers in their standard form. All the terms must be separated by a space, with no extra space at the end of a line.
Note: Simple chopping is assumed without rounding.
Sample Input 1:
3 12300 12358.9
Sample Output 1:
YES 0.123*10^5
Sample Input 2:
3 120 128
Sample Output 2:
NO 0.120*10^3 0.128*10^3
题目要求
将两个不超过10^100的浮点数按照输入输入的精确度表示,然后比较两个浮点数是否相同,如果相同则输出 YES,并将使用科学计数法表示的数字输出;如果不相同,则输出NO,并将两个数字以科学计数法输出;
解题思路
题目要求不超过10^100,那么这个浮点数只能用数组来表示;数字大小的比较可以通过比较其所对应的的ASCII,即不用char来表示每一个数字,通过字符的比较即可得到数字是否相同;
void getRidZero() 这一个函数用于将num[]数组清除前导零和小数点,然后将剩下的复制到数组pNum()中;同时将小数点的位置以及给予的浮点数第一个非零的数字记录在decimalPoint和index中;
void formatPrint()这一个函数用于将浮点数格式化输出;其中decimalPoint-index表示的是科学计数法的指数;decimalPoint1-index>=0说明原来的数大于0,如:123.2223;如果decimalPoint1-index<=0则说明是纯小数,如:0.00123,它的index=4,decimalPoint=1,小数点占了一位,因此指数需要将decimalPoint-index的值+1;
对于两个0比较,如:0000和000.000则先判断是否都为0,然后再输出;
数组的大小开到10000,是开始时开到100,发现没有AC,是因为题目给出的是数字位数不超过100,但数字的前导零的个数是不确定的;
需要注意的要点:结尾需要使用0进行补足
C语言代码
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
//用于将数组的前导零和小数点去掉,并将num[]数组的其他字符保存在 pNUm[]中
void getRidZero(char num[10000], int *index, int *decimalPoint, char pNum[10000])
{
//做一个循环除去开头的零和小数点
for (int i = 0; i < 10000; i++)
{
if (num[i] != '0'&&num[i] != '.'&&num[i] != '\0')
{
*index = i;
break;
}
}
//用于获取小数点的位置
for (int i = 0; i < 10000; i++)
{
if (num[i] == '\0' || num[i] == '.')
{
*decimalPoint = i;
break;
}
}
int j = 0;
for (int i = *index; i < 10000; i++)
{
if (num[i] == '\0' || num[i] < 0)
{
pNum[j] = '0';
j++;
}
else if (num[i] == '.')
{
continue;
}
else
{
pNum[j] = num[i];
j++;
}
}
}
//用于将pNum[]中保存的数按照科学计数法输出
void formatPrint(int accuracy, char pNum[10000], int decimalPoint, int index)
{
printf("0.");
for (int i = 0; i < accuracy; i++)
{
printf("%C", pNum[i]);
}
if (decimalPoint - index >= 0)
{
printf("*10^%d", decimalPoint - index);
}
else
{
printf("*10^%d", decimalPoint - index + 1);
}
}
int main() {
int accuracy;
char num1[10000];
char num2[10000];
char pNum1[10000];
char pNum2[10000];
//用于记录小数点的位置
int decimalPoint1 = 0;
int decimalPoint2 = 0;
//用于记录数字开始的位置
int index1 = 0;
int index2 = 0;
bool equal = true;
scanf("%d %s %s", &accuracy, num1, num2);
getRidZero(num1, &index1, &decimalPoint1, pNum1);
getRidZero(num2, &index2, &decimalPoint2, pNum2);
for (int i = 0; i < accuracy; i++)
{
if (pNum1[i] != pNum2[i])
{
equal = false;
}
}
if ((index1 - decimalPoint1) != (index2 - decimalPoint2))
{
equal = false;
}
bool notZero = false;
//判断00000000 和000000.000000000
for (int i = 0; i < 5000; i++)
{
if (pNum1[i] != '0' || pNum2[i] != '0')
{
//证明不是0
notZero = true;
break;
}
}
if (!notZero) //证明都是0 然后输出 0.0000*10^0 ,是第六个测试点
{
printf("YES 0.");
for (int i = 0; i < accuracy; i++)
{
printf("%C", '0');
}
printf("*10^%d", 0);
}
else if (equal) //如果两个数相等
{
printf("YES ");
formatPrint(accuracy, pNum1, decimalPoint1, index1);
}
else //如果两个数不想等
{
printf("NO ");
formatPrint(accuracy, pNum1, decimalPoint1, index1);
//输出第二个数
printf(" ");
formatPrint(accuracy, pNum2, decimalPoint2, index2);
}
system("pause");
return 0;
}
测试用例
- 5 0000.0000123 0.0000123
- 4 000123 00123.005
- 4 00000 000.000001
- 4 00.000 00000
- 4 0.01 0.01000005