SGU 987654321 problem
题目大意
输入N,输出有多少个N位数,满足平方的后9位是987654321
算法思路
对于一个数v,令b = v % 1000000000,a = v - b
因为
v2=(a+b)2=a2+2ab+b2=a(a+2b)+b2
而1000000000 | a,故
v2
的后9位只与b有关
通过dfs找出所有满足条件的b,记个数为tot,并统计N < 10的答案
对于
N≥10
的数,第一位有9种取值,后9位共有tot种取值,其他位有10种取值
通过乘法原理得出答案
时间复杂度: 远小于 O(109)
代码
/**
* Copyright (c) 2015 Authors. All rights reserved.
*
* FileName: 107.cpp
* Author: Beiyu Li <sysulby@gmail.com>
* Date: 2015-05-21
*/
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
typedef long long LL;
typedef pair<int, int> Pii;
const int inf = 0x3f3f3f3f;
const LL infLL = 0x3f3f3f3f3f3f3f3fLL;
const int val = 987654321;
int res[10], tot;
vector<int> vec;
void dfs(int d, int p)
{
if (d == 10) return;
int sz = vec.size();
rep(i,sz) For(j,1,9) {
int v = j * p + vec[i];
LL t = (LL)v * v;
if (t % 1000000000 == val) ++res[d], ++tot;
if (t % (p * 10) == val % (p * 10)) vec.push_back(v);
}
dfs(d + 1, p * 10);
}
int main()
{
int n;
scanf("%d", &n);
vec.push_back(0);
dfs(1, 1);
printf("%d", n < 10? res[n]: 9 * tot);
rep(i,n-10) putchar('0'); puts("");
return 0;
}