PAT甲级1060. Are They Equal

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值