2017 省赛 山东 B Quadrat 【打表】【规律】

来源:互联网 发布:读出文字的软件 编辑:程序博客网 时间:2024/06/06 00:07

Quadrat

Time Limit: 1000MS Memory Limit: 65536KB

Submit Statistic Discuss

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.

Example Input

25 02 1

Example Output

412

Hint

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

Author

“浪潮杯”山东省第八届ACM大学生程序设计竞赛(感谢青岛科技大学)

题目链接:

SDUT 3894 Quadrat

题目大意:

求满足以下条件

①.这个数为n位(可以有前导零)

②.取它的平方的后n位,与它本身每一位对应之差≤d(这里的差指的是数字之间的距离,而这个距离是将数字按圈排列,0与9相邻所求得的)

的数字的个数。

解题思路:

实在是不知道怎么做,最后选择打表看看,然后写出了以下代码:

#include <bits/stdc++.h>using namespace std;typedef long long LL;const int MAX = 10005;const int MOD = 1e9+7;const int INF = 0x3f3f3f3f;int a[15][15];/*{    {0,1,2,3,4,5,4,3,2,1};    {1,0,1,2,3,4,5,4,3,2};    {2,1,0,1,2,3,4,5,4,3};    {3,2,1,0,1,2,3,4,5,4};    {4,3,2,1,0,1,2,3,4,5};    {5,4,3,2,1,0,1,2,3,4};    {4,5,4,3,2,1,0,1,2,3};    {3,4,5,4,3,2,1,0,1,2};    {2,3,4,5,4,3,2,1,0,1};    {1,2,3,4,5,4,3,2,1,0};};*/LL mypow[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000};int main(){    memset(a, 0, sizeof(a));    for(int i = 0; i <= 9; ++i)    {        for(int j = 0; j <= 9; ++j)        {            a[i][j] = abs(i-j);            if(a[i][j] > 5) a[i][j] = 10 - a[i][j];            //cout << a[i][j] << " ";        }        //puts("");    }    for(int n = 1; n <= 7; ++n)    {        for(int eps = 0; eps <= 3; ++eps)        {            int tot = 0;            for(int i = 0; i < mypow[n]; ++i)            {                //cout << "i=" << i << endl;                int tt = i;                LL tm = (i%mypow[n])*(i%mypow[n]);                tm %= mypow[n];                int j;                for(j = 0; j < n; ++j)                {                    if(a[tm%10][tt%10] > eps) break;                    tm /= 10;                    tt /= 10;                }                if(j == n)                {                    ++tot;//                    cout << i << endl;                }            }            cout << tot << " ";            //cout << "tot=" << tot << endl;        }        puts("");    }    return 0;}

运行后的结果整理后是这样的:

 n\d  0  1    2      3 1    4  4    8      8 2    4  12   40     56 3    4  36   200    392 4    4  108  1000   2744 5    4  324  5000   19208 6    4  972  25000  134456 7    4  2916 125000 941192
观察发现,对应的【第i行的第j列的值】等于【第i-1行第j列的值】*【(j*2)-1】
然后打表就可以了,要注意精度哦。

Mycode:

#include <bits/stdc++.h>using namespace std;typedef long long LL;const int MAX = 10005;const int MOD = 1e9+7;const int INF = 0x3f3f3f3f;LL ans[20][5];void init(){    ans[1][0] = ans[1][1] = 4;    ans[1][2] = ans[1][3] = 8;    for(int n = 2; n <= 18; ++n)        for(int d = 0; d <= 3; ++d)            ans[n][d] = ans[n-1][d] * (d * 2 + 1);}int main(){    init();    int t;    int n, d;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&d);        printf("%lld\n", ans[n][d]);    }    return 0;}



原创粉丝点击