zoukankan      html  css  js  c++  java
  • ural 1698. Square Country 5(记忆化搜索)

    1698. Square Country 5

    Time limit: 2.0 second
    Memory limit: 64 MB
    The first arithmetical operation taught to the children of the Square country is the calculation of squares of positive integers. At the first lesson the children are provided with “easy” numbers, calculating a square of which can be done by writing a few digits in front of them (i.e. 76 is an easy number because 762 = 5776). Of course, the numbers cannot contain leading zeroes. The task shouldn't be too difficult, so the easy numbers shouldn't contain more than n digits. How many different easy numbers can teachers prepare for the first lesson?

    Input

    The only input line contains an integer n (1 ≤ n ≤ 2000), the maximal length of the easy number the children can be provided with.

    Output

    Output the number of different easy numbers consisting of at most n digits.

    Sample

    inputoutput
    1
    3

    题意:

    方块国的孩子们学到的第一个算术运算是正整数的平方计算.孩子们首先学的是那些"简单"数字的平方计算.所谓简单数字就是那些只需要在原数后加几个数字就可得到原数平方的数字(例如,76是简单数字,因为762=5776).当然,所有`数字都不能包含前导0.平方运算不能太麻烦,所以简单数字都不能超过n位.老师们总共可以准备多少简单数字?

    输入

    只有一个数字n(1<=n<=2000),表示给孩子们的简单数字的最大长度.

    输出

    输出不超过n位的简单数字个数.

    [编辑]样例

    [编辑]样例输入

    1

    [编辑]样例输出

    3

    思路:

    进行记忆化搜索,利用大数乘的方法,寻找自守数;

    前道知识:

    如果某个数的平方的末尾几位数等于这个数,那么就称这个数为自守数。
    显然,5和6是一位自守数(5x5=25 6x6=36)
    25x25=625 76x76=5776,所以25和76是两位自守数。
    自守数有一个特性,以他为后几位的两个数相乘,乘积的后几位仍是这个自守数。因为5时自守数,所以以5为个位数的两个数相乘,乘积的个位仍然是5;76是自守数,所以以76为后两位数的两个数相乘,其结果的后两位仍是76,如176x576=101376。
    虽然0和1的平方的个位数仍然是0和1,但是他们太“平凡”了,研究他们没有意义,所以不算自守数。
    三位自守数是625和376,四位自守数是0625和9376,五位自守数是90625和09376......
    我们可以看到,(n+1)位的自守数出自n位的自守数。由此得出,如果知道n位的自守数a,那么(n+1)位的自守数应当由a前面加上一个数构成。
    实际上,简化一下,还能发现如下规律:
    5+6=11
    25+76=101
    625+376=1001
    ......
    所以,两个n位自守数,他们的和等于10^n+1
     
    代码:
     1 #include <iostream>
     2 #include <string>
     3 #include<cstring>
     4 #include <queue>
     5 #include <vector>
     6 #include <map>
     7 #include <algorithm>
     8 #include <cmath>
     9 #include <cstdio>
    10 
    11 
    12 
    13 using namespace std;
    14 int n, ans;
    15 int a[2005];
    16 int b[2005];
    17 
    18 
    19 
    20 bool check(int k)
    21 {//计算平方后的第k+1位的数值;
    22     b[k] = 0;
    23     for (int i = 0; i <= k; ++i)
    24         b[k] += a[i] * a[k - i];
    25     if (k)
    26         b[k] += b[k - 1] / 10;
    27     return b[k] % 10 == a[k];
    28 }
    29 
    30 void dfs(int k)
    31 {
    32     if (k >= n)
    33         return;
    34     for (int i=9;i>=0;--i)
    35     {
    36         a[k] = i;
    37         if (check(k))
    38         {
    39             if (a[k])
    40             {//第k+1位数不是0,表示产生了新的自守数;
    41                 ans++;
    42             }
    43             dfs(k + 1);
    44         }
    45     }
    46 }
    47 
    48 
    49 
    50 int main()
    51 {
    52     scanf("%d", &n);
    53     dfs(0);
    54     printf("%d
    ", ans);
    55 }
    View Code
  • 相关阅读:
    Linux下管道编程
    【Windows】用信号量实现生产者-消费者模型
    初识【Windows API】--文本去重
    HDU 5183 Negative and Positive (NP) --Hashmap
    【ASC 23】G. ACdream 1429 Rectangular Polygon --DP
    UVALive 4670 Dominating Patterns --AC自动机第一题
    POJ 2225 / ZOJ 1438 / UVA 1438 Asteroids --三维凸包,求多面体重心
    我也来写2014年总结
    UVALive 4870 Roller Coaster --01背包
    UVALive 4864 Bit Counting --记忆化搜索 / 数位DP?
  • 原文地址:https://www.cnblogs.com/zhangchengbing/p/3426593.html
Copyright © 2011-2022 走看看