山东省第八届ACM省赛 Quadrat(打表找规律)

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

2
5 0
2 1

 

Example 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 ,且平方后模 10^n 与原来数之间的差距不大于 d (每一位字符差距和)。

 

思路

对于 10 以内的数,假如 d=0 时,只有四个数满足要求,分别为 0、1、5、6 。

假如 d=2 时,有八个数满足要求: 0、1、2、4、5、6、7、9 。

写一个暴力的程序当然很简单咯~

所以嘛!先用它来打表看看,找出 1<=n<=4 范围内所有 0<=d<=3 的答案。

1:      4 4 8 8
2:      4 12 40 56
3:      4 36 200 392
4:      4 108 1000 2744

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

总结

注意数据大小范围,要用long long型。 看到数据那么大,一个想到的应该就是找规律啦。 打表要打对喔,也要方便自己找到规律的~  
还有! 嗯,读题的时候还是要快一点的~这个得练起来呢~
#include <cstdio>
#include <iostream>
#include <cstring>
#include <math.h>
using namespace std;

int main()
{
    //freopen("1.txt", "r", stdin);
    int t;
    scanf("%d", &t);
    while( t --)
    {
        int n, d;
        scanf("%d%d", &n, &d);
        long long ans;
        if(d == 0) ans = 4;
        if(d == 1) ans = 4 *pow(3, n - 1);
        if(d == 2) ans = 8 * pow(5, n - 1);
        if(d == 3) ans = 8 * pow(7, n - 1);
        cout << ans << endl;
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值