Quadrat
Time Limit: 1000 ms Memory Limit: 65536 KiB
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, =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,1≤t≤72. Each of the next t lines contains one test case: two numbers n(1≤n≤ 18) and d(0≤ d≤3).
Output
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。要注意这题是一个环,数字0和9是相邻的,因此例如距离数字8最多3的数字是5,6,7,8,9,0和1。
思路
看不出怎么做,只能打印,找规律
10
以内的数,假如 d=0
时,只有四个数满足要求,分别为 0
、
1
、
5
、
6
。
假如 d=2
时,有八个数满足要求: 0
、
1
、
2
、
4
、
5
、
6
、
7
、
9
打表代码:
#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;
}