您的位置:首页 > 其它

2017年山东省第八届ACM大学生程序设计竞赛 B Quadrat(sdut 3894) 打表找规律

2017-07-24 17:11 429 查看
Quadrat
Time Limit: 1000MS
Memory Limit: 65536KB
[align=center][/align]
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 lastn 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 lastn 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 numbersn(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 mostd 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

    没想到这是一道打表找规律的题目...当时省赛看着没人做,这题连看都没看= =题意是说有T组数据,每组数据其中n为数字的位数,d为数字的最大差,问有几个数字符合要求。这个要求就是说将一个数平方,然后将这个平方数取原来位数的后几位,这几位数字每一位的差都要小于等于d。比如25,平方之后是625,舍去之后为25,距离是相同的,都为0。再比如21,21的平方为441,舍去后得到41,与21的差第一位为2,第二位为0,所以d为2。

    要注意这题是一个环,0到9的距离不是9而是1。

    接下来这个题就通过打表找规律了,打出n在[1,6],d在[0,3]范围的数就足够了(一开始没注意d的范围打到了5....),下面是打表程序:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;

int main()
{
int T;
int n,d;
long long i,j;
/*scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&d);*/
for(n=1;n<=6;n++)
{
for(d=0;d<=5;d++)

be0f
{
long long m=1;
for(i=1;i<=n;i++)
{
m*=10;
}
if(d==0)
{
cout<<4<<" ";
continue;
}
else
{
int ans=0;
for(i=0;i<m;i++)
{
int flag=0;
long long t=i;
long long p=t%m*t%m;
for(j=1;j<=n;j++)
{
int dis=abs(t%10-p%10);
if(dis>5)
dis=10-dis;
if(dis>d)
flag=1;
t/=10;
p/=10;
}
if(!flag)
{
//cout<<i<<"!!"<<endl;
ans++;
}
}
cout<<ans<<" ";
}
}
cout<<endl;
}
return 0;
}




    通过表格可以发现,第一行依次往下都是4,第二行依次乘3,第三行依次乘5,第四行依次乘7,然后初始化出来就行了。注意数据范围比较大,要用long long。

    下面AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long a[20][20];
long long b[5]={1,3,5,7};

int main()
{
int T;
int n,d;
int i,j;
scanf("%d",&T);
memset(a,0,sizeof(a));
a[1][0]=4;
a[1][1]=4;
a[1][2]=8;
a[1][3]=8;
for(i=2;i<=18;i++)
{
for(j=0;j<4;j++)
{
a[i][j]=a[i-1][j]*b[j];
}
}
while(T--)
{
scanf("%d%d",&n,&d);
cout<<a
[d]<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐