山东省第八届acm大赛 B题Quadrat

版权声明:转载请注明出处 https://blog.csdn.net/TY_GYY/article/details/83314823

Quadrat

Time Limit: 1000 ms Memory Limit: 65536 KiB

Submit Statistic

Problem Description

It is well-known that for any n there are exactly four n-digit numbers (including ones with leading zeros) that are self-squares: the last n digits of the square of such number are equal to the number itself. These four numbers are always suffixes of these four infinite sequences: 

...0000000000 
...0000000001 
...8212890625 
...1787109376 

For example, https://acm.sdut.edu.cn/image/3894.png=87909376, which ends with 09376.

You are required to count the numbers that are almost self-squares: such that each of the last n digits of their square is at most d away from the corresponding digit of the number itself. Note that we consider digits 0 and 9 to be adjacent, so for example digits that are at most 3 away from digit 8 are 5, 6, 7, 8, 9, 0 and 1. 

Input

The first line contains the number of test cases t,1t≤72. Each of the next t lines contains one test case: two numbers n(1n≤ 18) and d(0≤ d≤3). 

Output

扫描二维码关注公众号,回复: 5114108 查看本文章

For each test case, output the number of almost self-squares with length n and the (circular) distance in each digit from the square at most d in a line by itself.

Sample Input

2

5 0

2 1

Sample Output

4

12

Hint

In the second case, number 12's almost self-squares are: 00, 01, 10, 11, 15, 25, 35, 66, 76, 86, 90, 91

 

题意

找出有多少个数,它的长度为 n ,平方后将这个平方数取原来位数的后几位,这几位数字每一位的差都要小于等于d。比如25,平方之后是625,舍去之后为25,距离是相同的,都为0。要注意这题是一个环,数字09是相邻的,因此例如距离数字8最多3的数字是5,6,7,8,9,01

思路

  看不出怎么做,只能打印,找规律

10 以内的数,假如 d=0 时,只有四个数满足要求,分别为 0156 

假如 d=2 时,有八个数满足要求: 01245679

打表代码:

#include<bits/stdc++.h>

using namespace std;

int s[10];

bool Sum(int x, int d,int n) {

    int sum = 0,y=x*x;

    for (int i = 0; i < n; i++)

    {

         int a = fabs(x % 10 - y % 10);

         x /= 10; y /= 10;



         if (a > 5) a = 10 - a;

         if (a > d) return false;

    }

    return true;

}

int main()

{

    for (int i = 1; i <= 4; i++)

    {

         memset(s, 0, sizeof(s));

         int  m = pow(10, i);

         for (int k=0; k < m; k++)

         {

             for (int j = 0; j <= 3; j++)

             {

                  if (Sum(k, j, i)) s[j]++;

             }

         }





         for (int j = 0; j <= 3; j++)

         {

             printf("%d ", s[j]);

         }

         printf("\n");

    }

   

    return 0;

}

结果:

于是发现了 s[i][j]=s[i-1][j]*(2*j+1) 的规律,其中 i 为数的长度, j 为最大距离。

#include<bits/stdc++.h>  
using namespace std;  
long long s[20][5];  
int main()  
{  
    int n, k, t;  
  
    //init  
    s[1][0] = s[1][1] = 4;  
    s[1][2] = s[1][3] = 8;  
    for (int i = 2; i < 20; i++)  
    {  
        for (int j = 0; j < 5; j++) {  
            s[i][j] = s[i - 1][j] * (2 * j + 1);  
        }  
    }  
  
    scanf("%d", &t);  
    while (t--) {  
        scanf("%d %d", &n, &k);  
        printf("%lld\n", s[n][k]);  
    }  
    return 0;  
} 

 

猜你喜欢

转载自blog.csdn.net/TY_GYY/article/details/83314823