Codeforces 10C Digital Root

知识点:计数原理、数学推理、反向思考

题目

Not long ago Billy came across such a problem, where there were given three natural numbers A, B and C from the range [1, N], and it was asked to check whether the equation AB = C is correct. Recently Billy studied the concept of a digital root of a number. We should remind you that a digital root d(x) of the number x is the sum s(x) of all the digits of this number, if s(x) ≤ 9, otherwise it is d(s(x)). For example, a digital root of the number 6543 is calculated as follows: d(6543) = d(6 + 5 + 4 + 3) = d(18) = 9. Billy has counted that the digital root of a product of numbers is equal to the digital root of the product of the factors’ digital roots, i.e. d(xy) = d(d(x)d(y)). And the following solution to the problem came to his mind: to calculate the digital roots and check if this condition is met. However, Billy has doubts that this condition is sufficient. That’s why he asks you to find out the amount of test examples for the given problem such that the algorithm proposed by Billy makes mistakes.

输入

The first line contains the only number N (1 ≤ N ≤ 106).

输出

Output one number — the amount of required A, B and C from the range [1, N].

样例

输入1

4

输出1

2

输入2

5

输出2

6

提示

For the first sample the required triples are (3, 4, 3) and (4, 3, 3).

题意

Digital Root的递归定义为:若一个数字的各位数字之和小于等于9则为各位数字之和,否则为各位数字之和的Digital Root,记为d(x),且有d(xy)=d(d(x)d(y)),即乘积的Digital Root等于Digital Root的乘积的Digital Root。有人认为只要d©=d(d(A)d(B))就可以判断C=AB,其中A,B,C均为正整数且不超过N。存在A,B,C的不同组合,使得这个组合能反驳这个观点,要求输出组合数量。

思路

  1. Digital Root通俗的理解为,只要一个数字的位数大于1位就将各位数字相加得到新的数,重复操作得到的1位数就是Digital Root。
  2. 反驳观点的方法为,找到一对A,B,C使得AB≠C,但d(C)=d(d(A)d(B))。
  3. 正向考虑,发现AB≠C的组合太多,若使用三重循环分别枚举A,B,C,然后求d(A),d(B),d(C)判断d(C)=d(d(A)d(B)),时间复杂度为O(n^3),会超时。
  4. 反向考虑,所有能反驳观点的组合中,必满足d(C)=d(d(A)d(B)),但AB≠C。而根据通俗理解可以知道等号左右取值范围只能是0~9,但对0~9中任意一个数字(设为e)而言,等号左右等于e的组合有很多,根据分步计数原理,为满足d(C)=e的C的个数乘以满足d(d(A)d(B))=e的A的个数乘满足d(d(A)d(B))=e的B的个数,分类计数原理得总数为e取0~9时满足上述条件的A,B,C组合个数的和。再从得到的和中减去满足AB=C的组合。
  5. 分析满足d(C)=d(d(A)d(B))的组合个数。考虑到A,B,C都小于N,可以枚举1~N的所有值,并计算值的Digital Root,就可以统计Digital Root为0~9的数字分别为有多少,从而在后面的处理使用O(1)得到d(x)=e时x的取值个数,x取A,B,C即可得到A,B,C的取值个数。
  6. 通过d(C)=e计算C的个数可直接用上述方法。为了通过d(d(A)d(B))=e计算A,B的组合个数,可枚举d(A),d(B)(属于0~9),如果d(d(A)d(B))=e则把d(A),d(B)的A,B的取值个数相乘再乘以之前算出的d(C)的C的个数。当然因为d(d(A)d(B))算出的值可用作得到d(C)的个数,故可以直接把d(A),d(B),d(d(A)d(B))的A,B,C的取值个数相乘。
  7. 分析AB=C的组合个数。AB=C<=N,所以B<=N/A,即B取值为1~N/A,可枚举A从1~N,N/A为B的取值个数,而C可由A,B计算得到,A,B确定时,C的取值只有一个,所以组合个数为A从1~N时B的取值个数的和。
  8. 分析d(x)的计算方法,可直接使用定义计算,另一种计算方法需要证明:
    当x%9==0时,d(x)=9;
    当x%9!=0时,d(x)=x%9.
    证明如下:
    x==9时,d(x)=9
    x<9时,d(x)=x%9
    x>9时,
    设x=x0+x1*10+x2*100+…+xn*1000…
    =x0+x1+x2+…+xn+x1*9+x2*99+…+xn*999…
    =d(x)+9*(x1*1+x2*11+…+xn*111…)
    d(x)=x%9
    证毕。
    (数论杀我)
    实现思路见代码。

代码

//克服WA难,终得AC
#include"bits/stdc++.h"
#define ll long long
#define rep(i,a,b) for(ll i=a;i<b;i++)
#define reb(i,a,b) for(ll i=a;i<=b;i++)
#define rev(i,a,b) for(ll i=a-1;i>=b;i--)
#define red(i,a,b) for(ll i=a;i>=b;i--)
#define clr(arr,val) memset(arr,val,sizeof arr)
using namespace std;

ll cnt[20];//1~N中d(x)=i的个数

ll d(ll x) {
   
  return x%9?x%9:9;
}

int main() {
   
  ll n;
  cin>>n;
  //枚举1~N,对d(i)出现次数计数
  reb(i,1,n) cnt[d(i)]++;
  ll ans=0;
  //计算d(C)=d(d(A)d(B))的个数。枚举d(A)、d(B),cnt[i]为A的个数,cnt[j]为B的个数,cnt[d(i*j)]为通过d(A)和d(B)计算出的C的个数。
  reb(i,0,9) reb(j,0,9) ans+=cnt[i]*cnt[j]*cnt[d(i*j)];
  //计算AB=C的个数。枚举A,计算B的个数,从答案中减去
  reb(i,1,n) ans-=n/i;
  cout<<ans<<endl;
  return 0;
}
全部评论

相关推荐

焦虑中,不知道怎么办了。。。
西北上单:应该放俩项目合理一些 我是一个业务开发项目 一个AI项目和你这个写的亮点差不多
你的简历改到第几版了
点赞 评论 收藏
分享
02-26 13:56
已编辑
重庆财经学院 Java
King987:你有实习经历,但是写的也太简单了,这肯定是不行的,你主要要包装实习经历这一块,看我的作品,你自己包装一下吧,或者发我,我给你出一期作品
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# AI面会问哪些问题? #
24929次浏览 492人参与
# 中国电信笔试 #
31111次浏览 283人参与
# 开放七大实习专项,百度暑期实习值得冲吗 #
14163次浏览 209人参与
# 你的实习产出是真实的还是包装的? #
18842次浏览 330人参与
# 如果秋招能重来,我会____ #
96703次浏览 500人参与
# 春招至今,你的战绩如何? #
60095次浏览 546人参与
# 厦门银行科技岗值不值得投 #
7498次浏览 186人参与
# i人适合做什么工作 #
36928次浏览 124人参与
# 我是面试官,请用一句话让我破防 #
79522次浏览 219人参与
# 哪些公司真双非友好? #
69209次浏览 287人参与
# 金三银四,你的春招进行到哪个阶段了? #
21573次浏览 277人参与
# 找AI工作可以去哪些公司? #
7714次浏览 186人参与
# 从事AI岗需要掌握哪些技术栈? #
7721次浏览 251人参与
# 投递几十家公司,到现在0offer,大家都一样吗 #
339935次浏览 2165人参与
# 面试尴尬现场 #
220770次浏览 861人参与
# 五一之后,实习真的很难找吗? #
102806次浏览 584人参与
# 你做过最难的笔试是哪家公司 #
30253次浏览 193人参与
# 你小时候最想从事什么职业 #
159844次浏览 2072人参与
# 应届生第一份工资要多少合适 #
20487次浏览 84人参与
# 阿里笔试 #
176516次浏览 1302人参与
# 一张图晒出你司的标语 #
3835次浏览 72人参与
# 面试被问期望薪资时该如何回答 #
382470次浏览 2163人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务