PAT 甲级-数学问题

阅读原文

数学可以提高思维能力,而算法最需要的就是思维能力,所以数学和算法题总是绕不开的,PAT 中就有专门的数学类型题但只是将需要大量计算的数学题用算法的方式进行解答,但还是有一部分题做到了很好的结合。举个不恰当的例子:圆的面积就是将其不断分割成可以用来计算的矩形和三角形,按照数学的思路就是用圆周率,而算法就是模拟切割的过程不断计算(当然实际肯定不是这样),不过计算机被创造出来的初衷好像就是做这种事

思想解释

简单数学

一些不需要算法,仅仅使用基础数学知识的问题,一般考察的逻辑数理能力

公约公倍数
int gcd(int a, int b)
{ //求最大公约数

    return !b ? a : gcd(b, a % b);

}

最小公倍数: ( a × b ) / g c d ( a , b ) (a×b)/gcd(a,b) (a×b)/gcd(a,b)

分数

分数的存储一般使用结构体的方式

struct Fraction
{
    int up,down;
};

至于其运算也是使用不同的公式对分数的分子分母进行操作

分数许多情况下需要化简,其化简过程有三个:

  1. 判断 down 是否为负数,是则使分子和分母都变为其相反数

  2. 判断分子是否为 0,是则分母化为 1

  3. 求分子和分母的绝对值是否有最大公约数,有则转换为除公约数的情况

分数的输出有多种情况,输出前必须化简

  • 需要判断分母是否为 1,是则输出整数

  • 分子的绝对值大于分母,则是一个假分数,输出带分数的形式

素数

判断代码:

bool isPrime(int a)
{

    if (a <= 1)
    {
        return false;
    }

    int sqr = (int)sqrt(1.0 * a);
    for (int i = 2; i <= sqr; i++)
    {
        if (a % i == 0)
        {
            return false;
        }
    }
    return true;

}

手动表:

    vector<int> prime(50000, 1);
    for (int i = 2; i * i < 50000; i++)
    { //根据特性,将不是素数的置为 0
        for (int j = 2; j * i < 50000; j++)
        {
            prime[j * i] = 0;
        }
    }
质因子

一个整数被分解成一个或多个质数的乘积,但是质因子相乘到 29 时 ( 2 × 3 × ⋅ ⋅ ⋅ × 29 2×3×···×29 2×3××29) 就已经超过了 int 型的范围,所以保存因子的数组大小为 10 即可

大数存储与运算

大数使用读入字符串,反向存储到 int 数组中,运算根据规则定义即可

#include <iostream>
#include <cstring>
using namespace std; 

struct bign //定义大数结构体
{

    int num[1000], len;
    bign() //析构函数,使每次定义时初始化
    {
        memset(num, 0, sizeof(num));
        len = 0;
    }

}; 

bign change(string str) //输入转换为大数形式
{

    bign temp;
    temp.len = str.length();
    for (int i = 0; i < temp.len; i++)
    {
        temp.num[i] = str[temp.len - i - 1] - '0'; //逆向非零赋值
    }
    return temp;

}

int compare(bign a, bign b) //比较大小,A 大返回 1,B 大返回-1,相等返回 0
{

    if (a.len > b.len) //A 的长度大于 B
    {
        return 1;
    }
    else if (a.len > b.len) //A.length<B.length
    {
        return -1;
    }
    else //长度相同
    {
        for (int i = a.len - 1; i >= 0; i--)
        {                            //从高位到低位比较
            if (a.num[i] > b.num[i]) //只要有一个大就是大
            {
                return 1;
            }
            else if (a.num[i] < b.num[i])
            {
                return -1;
            }
        }
        return 0; //全部排除为相等
    }

}

void show(bign bignum) //输出
{

    for (int i = bignum.len - 1; i >= 0; i--)
    {
        cout << bignum.num[i];
    }

}

bign multi(bign a, int b)
{

    bign c;
    int carry = 0;
    for (int i = 0; i < a.len; i++)
    {
        int temp = a.num[i] * b + carry;
        c.num[c.len++] = temp % 10;
        carry = temp / 10;
    }
    while (carry != 0)
    {
        c.num[c.len++] = carry % 10;
        carry /= 10;
    }
    return c;

}

int main()
{

    string str;
    cin >> str;
    bign bigtemp = change(str);
    show(bigtemp);
    system("pause");
    return 0;

}

类型练习

1069

题目:The Black Hole of Numbers

For any 4-digit integer except the ones with all the digits being the same, if we sort the digits in non-increasing order first, and then in non-decreasing order, a new number can be obtained by taking the second number from the first one. Repeat in this manner we will soon end up at the number 6174 – the black hole of 4-digit numbers. This number is named Kaprekar Constant.

For example, start from 6767, we’ll get:

7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174
… …

Given any 4-digit number, you are supposed to illustrate the way it gets into the black hole.

Input Specification:

Each input file contains one test case which gives a positive integer N in the range ( 0 , 1 0 4 ) (0,10^4) (0,104).

Output Specification:

If all the 4 digits of N are the same, print in one line the equation N - N = 0000. Else print each step of calculation in a line until 6174 comes out as the difference. All the numbers must be printed as 4-digit numbers.

Sample Input 1:

6767

Sample Output 1:

7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174

Sample Input 2:

2222

Sample Output 2:

2222 - 2222 = 0000

思路: 使用字符串的形式进行输入,对字符串进行升序和降序排序,转换为整数求结果,再将结果转换为字符串判断是否为 6174 或 0000

代码:

#include <iostream>
#include <algorithm>
using namespace std;

bool cmp(char a, char b)
{
    return a > b; //递减排序
}
int main()
{
    string str;
    cin >> str;
    str.insert(0, 4 - str.length(), '0');//不足 4 位前面补 0
    do
    {
        string a = str, b = str;
        sort(a.begin(), a.end(), cmp);//降序排序
        sort(b.begin(), b.end());//升序排序
        int result = stoi(a) - stoi(b);//转换求值
        str = to_string(result);//再转为字符串
        str.insert(0, 4 - str.length(), '0');//补零
        cout << a << " - " << b << " = " << str << endl;

    } while (str != "6174" && str != "0000");
    syste("pause");
    return 0;
}
1104

题目:Sum of Number Segments

Given a sequence of positive numbers, a segment is defined to be a consecutive subsequence. For example, given the sequence { 0.1, 0.2, 0.3, 0.4 }, we have 10 segments: (0.1) (0.1, 0.2) (0.1, 0.2, 0.3) (0.1, 0.2, 0.3, 0.4) (0.2) (0.2, 0.3) (0.2, 0.3, 0.4) (0.3) (0.3, 0.4) and (0.4).

Now given a sequence, you are supposed to find the sum of all the numbers in all the segments. For the previous example, the sum of all the 10 segments is 0.1 + 0.3 + 0.6 + 1.0 + 0.2 + 0.5 + 0.9 + 0.3 + 0.7 + 0.4 = 5.0 0.1 + 0.3 + 0.6 + 1.0 + 0.2 + 0.5 + 0.9 + 0.3 + 0.7 + 0.4 = 5.0 0.1+0.3+0.6+1.0+0.2+0.5+0.9+0.3+0.7+0.4=5.0.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N, the size of the sequence which is no more than 105. The next line contains N positive numbers in the sequence, each no more than 1.0, separated by a space.

Output Specification:

For each test case, print in one line the sum of all the numbers in all the segments, accurate up to 2 decimal places.

Sample Input:

4
0.1 0.2 0.3 0.4

Sample Output:

5.00

思路: 找出每个数字在不同片段出现的次数,规律为 i × ( n + 1 − i ) i×(n+1-i) i×(n+1i),注意精度可能不足

代码:

#include <iostream>
using namespace std; 

int main() {

    int n;
    cin >> n;
    long long sum = 0;
    double temp;
    for (int i = 1; i <= n; i++) { 
        cin >> temp;
        sum += (long long)(temp * 1000) * i * (n - i + 1);
    }
    printf("%.2f", sum / 1000.0);
    return 0;

}

1008

题目:Elevator

The highest building in our city has only one elevator. A request list is made up with N positive numbers. The numbers denote at which floors the elevator will stop, in specified order. It costs 6 seconds to move the elevator up one floor, and 4 seconds to move down one floor. The elevator will stay for 5 seconds at each stop.

For a given request list, you are to compute the total time spent to fulfill the requests on the list. The elevator is on the 0th floor at the beginning and does not have to return to the ground floor when the requests are fulfilled.

Input Specification:

Each input file contains one test case. Each case contains a positive integer N, followed by N positive numbers. All the numbers in the input are less than 100.

Output Specification:

For each test case, print the total time on a single line.

Sample Input:

3 2 3 1

Sample Output:

41

思路: 循环处理,根据大小关系处理上楼下楼,每次更新 now 代表的楼层

代码:

#include <iostream>
using namespace std;

int main()
{
    int n;
    cin >> n;
    int now = 0, ans = 0, temp;
    while (n--)
    {
        cin >> temp;
        if (temp >= now)
        {
            ans += 6 * (temp - now) + 5;
        }
        else if (temp < now)
        {
            ans += 4 * (now - temp) + 5;
        }
        now = temp;
    }
    cout << ans;
    system("pause");
    return 0;
} 
1049

题目:Counting Ones

The task is simple: given any positive integer N, you are supposed to count the total number of 1’s in the decimal form of the integers from 1 to N. For example, given N being 12, there are five 1’s in 1, 10, 11, and 12.

Input Specification:

Each input file contains one test case which gives the positive N ( ≤ 2 30 ) N (≤2^{30}) N(230).

Output Specification:

For each test case, print the number of 1’s in one line.

Sample Input:

12

Sample Output:

5

思路: 直接循环必然超时,总结规律:从第一位(个位)到最高位,设 now 为当前位的数字,left 为 now 左边的所有数字构成的数字,right 是 now 右边的所有数字构成的数字。只需要一次次累加对于当前位 now 来说可能出现 1 的个数,然后把它们累加即可。a 表示当前的个位为 1,十位为 10,百位为 100 类推。

对于 now,有三种情况:

  1. now == 0 : 那么 ans += left * a; //因为 now==0 说明 now 位只有在 left 从 0~left-1 的时候会产生 1,所以会产生 left 次,但是又因为右边会重复从 0~999… 出现 a 次

  2. now == 1 : ans += left * a + right + 1;//now = 1 的时候就要比上一步多加一个当 now 为 1 的时候右边出现 0~right 个数导致的 now 为 1 的次数

  3. now >= 2 : ans += (left + 1) * a;//now 大于等于 2 就左边 0~left 的时候会在 now 位置产生 1,所以会产生 left 次,但是又因为右边会重复从 0~999… 出现 a 次

代码:

#include <iostream>
using namespace std; 

int main()
{

    int n;
    cin >> n;
    int left = 0, right = 0, a = 1, now = 1, ans = 0;
    while (n / a)
    {
        left = n / (a * 10), now = n / a % 10, right = n % a;
        if (now == 0)
        {
            ans += left * a;
        }
        else if (now == 1)
        {
            ans += left * a + right + 1;
        }
        else
        {
            ans += (left + 1) * a;
        }
        a *= 10;
    }
    cout << ans;
    system("pause");
    return 0;

}

1081

题目:Rational Sum

Given N rational numbers in the form numerator/denominator, you are supposed to calculate their sum.

Input Specification:

Each input file contains one test case. Each case starts with a positive integer N (≤100), followed in the next line N rational numbers a1/b1 a2/b2 ... where all the numerators and denominators are in the range of long int. If there is a negative number, then the sign must appear in front of the numerator.

Output Specification:

For each test case, output the sum in the simplest form integer numerator/denominator where integer is the integer part of the sum, numerator < denominator, and the numerator and the denominator have no common factor. You must output only the fractional part if the integer part is 0.

Sample Input 1:

5
2/5 4/15 1/30 -2/60 8/3

Sample Output 1:

3 1/3

思路: 根据文首分数的处理思路,对其进行处理即可

代码:

#include <iostream>
#include <cstdlib>
using namespace std;

long long gcd(long long a, long long b)
{
    return b == 0 ? abs(a) : gcd(b, a % b);
}
int main()
{
    long long n, a, b, suma = 0, sumb = 1, gcdvalue;
    scanf("%lld", &n);
    for (int i = 0; i < n; i++)
    {
        scanf("%lld/%lld", &a, &b);
        gcdvalue = gcd(a, b);
        a = a / gcdvalue;
        b = b / gcdvalue;
        suma = a * sumb + suma * b;
        sumb = b * sumb;
        gcdvalue = gcd(suma, sumb);
        sumb = sumb / gcdvalue;
        suma = suma / gcdvalue;
    }
    long long integer = suma / sumb;
    suma = suma - (sumb * integer);
    if (integer != 0)
    {
        printf("%lld", integer);
        if (suma != 0)
            printf(" ");
    }
    if (suma != 0)
        printf("%lld/%lld", suma, sumb);
    if (integer == 0 && suma == 0)
        printf("0");
    return 0;
}
1088

题目:Rational Arithmetic

For two rational numbers, your task is to implement the basic arithmetics, that is, to calculate their sum, difference, product and quotient.

Input Specification:

Each input file contains one test case, which gives in one line the two rational numbers in the format a1/b1 a2/b2 . The numerators and the denominators are all in the range of long int. If there is a negative sign, it must appear only in front of the numerator. The denominators are guaranteed to be non-zero numbers.

Output Specification:

For each test case, print in 4 lines the sum, difference, product and quotient of the two rational numbers, respectively. The format of each line is number1 operator number2 = result . Notice that all the rational numbers must be in their simplest form k a/b , where k is the integer part, and a/b is the simplest fraction part. If the number is negative, it must be included in a pair of parentheses. If the denominator in the division is zero, output Inf as the result. It is guaranteed that all the output integers are in the range of long int.

Sample Input 1:

2/3 -4/2

Sample Output 1:

2/3 + (-2) = (-1 1/3)
2/3 - (-2) = 2 2/3
2/3 * (-2) = (-1 1/3)
2/3 / (-2) = (-1/3)

Sample Input 2:

5/3 0/6

Sample Output 2:

1 2/3 + 0 = 1 2/3
1 2/3 - 0 = 1 2/3
1 2/3 * 0 = 0
1 2/3 / 0 = Inf

思路: 使用上方分数思想编写不同的算法函数进行运算即可,这里采用的是柳神代码

代码:

#include <iostream>
#include <cmath>
using namespace std; 
long long a, b, c, d; 
long long gcd(long long t1, long long t2)
{

    return t2 == 0 ? t1 : gcd(t2, t1 % t2);

}
void func(long long m, long long n)
{

    if (m * n == 0)
    {
        printf("%s", n == 0 ? "Inf" : "0");
        return;
    }
    bool flag = ((m < 0 && n > 0) || (m > 0 && n < 0));
    m = abs(m);
    n = abs(n);
    long long x = m / n;
    printf("%s", flag ? "(-" : "");
    if (x != 0)
        printf("%lld", x);
    if (m % n == 0)
    {
        if (flag)
            printf(")");
        return;
    }
    if (x != 0)
        printf(" ");
    m = m - x * n;
    long long t = gcd(m, n);
    m = m / t;
    n = n / t;
    printf("%lld/%lld%s", m, n, flag ? ")" : "");

}
int main()
{

    scanf("%lld/%lld %lld/%lld", &a, &b, &c, &d);
    func(a, b);
    printf(" + ");
    func(c, d);
    printf(" = ");
    func(a * d + b * c, b * d);
    printf("\n");
    func(a, b);
    printf(" - ");
    func(c, d);
    printf(" = ");
    func(a * d - b * c, b * d);
    printf("\n");
    func(a, b);
    printf(" * ");
    func(c, d);
    printf(" = ");
    func(a * c, b * d);
    printf("\n");
    func(a, b);
    printf(" / ");
    func(c, d);
    printf(" = ");
    func(a * d, b * c);
    return 0;

}

1078

题目:Hashing

The task of this problem is simple: insert a sequence of distinct positive integers into a hash table, and output the positions of the input numbers. The hash function is defined to be H ( k e y ) = k e y H(key)=key%TSize H(key)=key where TSize is the maximum size of the hash table. Quadratic probing (with positive increments only) is used to solve the collisions.

Note that the table size is better to be prime. If the maximum size given by the user is not prime, you must re-define the table size to be the smallest prime number which is larger than the size given by the user.

Input Specification:

Each input file contains one test case. For each case, the first line contains two positive numbers: M S i z e ( ≤ 1 0 4 ) MSize (≤10^4) MSize(104) and N ( ≤ M S i z e ) N (≤MSize) N(MSize) which are the user-defined table size and the number of input numbers, respectively. Then N distinct positive integers are given in the next line. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the corresponding positions (index starts from 0) of the input numbers in one line. All the numbers in a line are separated by a space, and there must be no extra space at the end of the line. In case it is impossible to insert the number, print “-” instead.

Sample Input:

4 4
10 6 4 15

Sample Output:

0 1 4 -

思路: 找到大于 Tsize 的最小的素数,然后使用二次探查法

如果 hashTable 里面 key % size 的下标对应的 hashTable 为 false, 说明这个下标没有被使用过,直接输出。否则 step 步长从 1 加到 size-1,一次次尝试是否能使 index = (key + step * step) % size; 所对应的位置没有元素,如果都没有找到就输出“-”,否则就输出这个找到的元素的位置
注意 是 (key + step * step) % size 而不是** (key % size + step * step)

代码:

#include <iostream>
using namespace std;

int size, n, hashTable[10100];

bool isprime(int num) //判断素数
{
    if (num == 1)
        return false;
    for (int i = 2; i * i <= num; i++)
        if (num % i == 0)
            return false;
    return true;
}

void insert(int key) //插入方法
{
    for (int step = 0; step < size; step++)
    {
        int index = (key + step * step) % size;
        if (hashTable[index] == 0)
        {
            hashTable[index] = 1;
            cout << index;
            return;
        }
    }
    cout << '-';
}

int main()
{
    cin >> size >> n;
    while (!isprime(size)) //找到第一个比 Tsize 大的素数
    {
        size++;
    }
    for (int i = 0; i < n; i++)
    {
        int key;
        cin >> key;
        if (i != 0)
        {
            cout << ' ';
        }
        insert(key);
    }
    return 0;
}
1096

题目:Consecutive Factors

Among all the factors of a positive integer N, there may exist several consecutive numbers. For example, 630 can be factored as 3 × 5 × 6 × 7 3×5×6×7 3×5×6×7, where 5, 6, and 7 are the three consecutive numbers. Now given any positive N, you are supposed to find the maximum number of consecutive factors, and list the smallest sequence of the consecutive factors.

Input Specification:

Each input file contains one test case, which gives the integer N ( 1 < N < 2 31 ) N(1<N<2^{31}) N(1<N<231).

Output Specification:

For each test case, print in the first line the maximum number of consecutive factors. Then in the second line, print the smallest sequence of the consecutive factors in the format factor[1]*factor[2]*...*factor[k] , where the factors are listed in increasing order, and 1 is NOT included.

Sample Input:

630

Sample Output:

3
5×6×7

思路: 使用双重循环嵌套,模拟连续的长度,不论长度多少,当前乘积不能被 num 整除就不符合条件,相反,只要能够整除不论其他因子为多少都符合条件

  • 数据规模为 int 型的范围,但中间计算乘积时可能导致溢出,所以存储为 long long

  • 因子 1 不包含在范围中,第一层循环从 2 开始,然后将第一层的变量 i 作为第二层循环的起始因子,不断自增模拟

  • 使用临时变量 temp(每次初始为 1)相乘第二层的循环变量 j,若 num 对 temp 不能整除,表示不符合条件跳出

代码:

#include <iostream>
#include <cmath>
using namespace std; 

long int num, temp; 
int main()
{

    cin >> num;
    int first = 0, len = 0, maxn = sqrt(num) + 1; //乘积因子的最大值为 n 的开根
    for (int i = 2; i <= maxn; i++)               //控制起始因子
    {
        int j;
        temp = 1;
        for (j = i; j <= maxn; j++) //控制连续因子
        {
            temp *= j;
            if (num % temp != 0) //不再符合跳出
            {
                break;
            }
        }
        if (j - i > len) //每次更新最长长度
        {
            len = j - i;
            first = i;
        }
    }

    if (first == 0)
    {
        cout << 1 << endl
             << num;
    }
    else
    {
        cout << len << endl;
        for (int i = 0; i < len; i++)
        {
            cout << first + i;
            if (i != len - 1)
            {
                cout << '*';
            }
        }
    }
    system("pause");
    return 0;

}

1059

题目:Prime Factors

Given any positive integer N, you are supposed to find all of its prime factors, and write them in the format N = p 1 k 1 × p 2 k 2 × ⋯ × p m k m N= p1^{k1}×p2^{k2}×⋯×pm^{km} N=p1k1×p2k2××pmkm.

Input Specification:

Each input file contains one test case which gives a positive integer N in the range of long int.

Output Specification:

Factor N in the format N = p1^k1*p2^k2**pm^km, where pi’s are prime factors of N in increasing order, and the exponent ki is the number of pi – hence when there is only one pi, ki is 1 and must NOT be printed out.

Sample Input:

97532468

Sample Output:

97532468=2^211171011291

思路: 建立素数表,遍历判断,符合条件整除当前因子后继续判断

  • 建立素数表:long int 的 sqrt 最大不超过 50000,也就是说因子只会在这里边产生,将数组初始值为 1,不符合条件的赋值为 0

  • 循环遍历,然后对每一个变量 i 进行素数判断,是素数就判断能否整除,能够整除在判断一次,判断当前因子出现了几次

代码:

#include <iostream>
#include <vector>
using namespace std;

vector<int> prime(50000, 1); //乘积因子不会大于 50000,建立素数表,初始为 1
long int num;
int main()
{
    for (int i = 2; i * i < 50000; i++)
    {
        for (int j = 2; j * i < 50000; j++)
        {
            prime[i * j] = 0; //将不是素数的标记为 0
        }
    }
    cin >> num;
    cout << num << '=';
    if (num == 1)
    {
        cout << 1;
    }
    bool state = false; //有无因子输出标志
    for (int i = 2; i < 50000 && num >= 2; i++)
    {
        int cnt = 0;                          //指数
        bool flag = false;                    //条件符合
        while (prime[i] == 1 && num % i == 0) //是素数而且可以整除
        {
            num /= i;
            cnt++;
            flag = true;
        }
        if (flag)
        {
            if (state)
            {
                cout << '*';
            }
            cout << i;
            state = true;
        }
        if (cnt > 1)
        {
            cout << '^' << cnt;
        }
    }
    return 0;
}
1023

题目:Have Fun with Numbers

Notice that the number 123456789 is a 9-digit number consisting exactly the numbers from 1 to 9, with no duplication. Double it we will obtain 246913578, which happens to be another 9-digit number consisting exactly the numbers from 1 to 9, only in a different permutation. Check to see the result if we double it again!

Now you are suppose to check if there are more numbers with this property. That is, double a given number with k digits, you are to tell if the resulting number consists of only a permutation of the digits in the original number.

Input Specification:

Each input contains one test case. Each case contains one positive integer with no more than 20 digits.

Output Specification:

For each test case, first print in a line “Yes” if doubling the input number gives a number that consists of only a permutation of the digits in the original number, or “No” if not. Then in the next line, print the doubled number.

Sample Input:

1234567899

Sample Output:

Yes
2469135798

思路: 大数类的转换和乘法,使用标记数组进行每个字符次数的判断

代码:

#include <iostream>
#include <vector>
#include <cstring>
using namespace std; 

struct bignum
{

    int num[25], len;
    bignum()
    {
        memset(num, 0, sizeof(num));
        len = 0;
    }

}; 

bignum add(bignum a, bignum b)
{

    bignum c;
    int carry = 0;
    for (int i = 0; i < a.len || i < b.len; i++)
    {
        int temp = a.num[i] + b.num[i] + carry;
        c.num[c.len++] = temp % 10;
        carry = temp / 10;
    }
    if (carry != 0)
    {
        c.num[c.len++] = carry;
    }
    return c;

}

bignum multi(bignum a, int b)
{

    bignum c;
    int carry = 0;
    for (int i = 0; i < a.len; i++)
    {
        int temp = a.num[i] * b + carry;
        c.num[c.len++] = temp % 10;
        carry = temp / 10;
    }
    while (carry != 0)
    {
        c.num[c.len++] = carry % 10;
        carry /= 10;
    }
    return c;

}

int main()
{

    string str;
    cin >> str;
    vector<int> flag(10, 0);
    bool p = true;
    bignum bign;
    bign.len = str.length();
    for (int i = 0; i < str.length(); i++)
    {
        bign.num[i] = str[bign.len - i - 1] - '0';
        flag[bign.num[i]]++;
    }
    bignum result = multi(bign, 2);
    for (int i = 0; i < result.len; i++)
    {
        flag[result.num[i]]--;
    }
    if (bign.len != result.len)
    {
        p = false;
    }
    else
    {
        for (int i = 1; i <= 9; i++)
        {
            if (flag[i])
            {
                p = false;
            }
        }
    }

    if (p)
    {
        cout << "Yes" << endl;
    }
    else
    {
        cout << "No" << endl;
    }
    for (int i = result.len - 1; i >= 0; i--)
    {
        cout << result.num[i];
    }
    system("pause");
    return 0;

}

1024

题目:Palindromic Number

A number that will be the same when it is written forwards or backwards is known as a Palindromic Number. For example, 1234321 is a palindromic number. All single digit numbers are palindromic numbers.

Non-palindromic numbers can be paired with palindromic ones via a series of operations. First, the non-palindromic number is reversed and the result is added to the original number. If the result is not a palindromic number, this is repeated until it gives a palindromic number. For example, if we start from 67, we can obtain a palindromic number in 2 steps: 67 + 76 = 143, and 143 + 341 = 484.

Given any positive integer N, you are supposed to find its paired palindromic number and the number of steps taken to find it.

Input Specification:

Each input file contains one test case. Each case consists of two positive numbers N and K, where N ( ≤ 1 0 10 ) N (≤10^{10}) N(1010) is the initial numer and K (≤100) is the maximum number of steps. The numbers are separated by a space.

Output Specification:

For each test case, output two numbers, one in each line. The first number is the paired palindromic number of N, and the second number is the number of steps taken to find the palindromic number. If the palindromic number is not found after K steps, just output the number obtained at the Kth step and K instead.

Sample Input 1:

67 3

Sample Output 1:

484
2

思路: 将操作的方法独立编写,使用次数和是否回文作为循环终止条件进行 while 循环,最后输出

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

struct bign
{
    int num[1000], len;
    bign()
    {
        memset(num, 0, sizeof(num));
        len = 0;
    }
};

bign change(string str)
{
    bign temp;
    temp.len = str.length();
    for (int i = 0; i < str.length(); i++)
    {
        temp.num[i] = str[temp.len - i - 1] - '0';
    }
    return temp;
}

bign add(bign a, bign b)
{
    bign c;
    int carry = 0;
    for (int i = 0; i < a.len || i < b.len; i++)
    {
        int temp = a.num[i] + b.num[i] + carry;
        c.num[c.len++] = temp % 10;
        carry = temp / 10;
    }
    if (carry != 0)
    {
        c.num[c.len++] = carry;
    }
    return c;
}

bool judge(bign a)
{
    for (int i = 0; i < a.len / 2; i++)
    {
        if (a.num[i] != a.num[a.len - 1 - i])
        {
            return false;
        }
    }
    return true;
}

int main()
{
    string str;
    int n;
    cin >> str >> n;
    bign a = change(str);
    int k = 0;
    while (k < n && judge(a) == false)
    {
        bign b = a;
        reverse(b.num, b.num + b.len);
        a = add(a, b);
        k++;
    }
    for (int i = a.len - 1; i >= 0; i--)
    {
        cout << a.num[i];
    }
    cout << endl
         << k;
    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值