HDU5710-Digit-Sum
来源:互联网 发布:linux rc.local sh 编辑:程序博客网 时间:2024/05/21 10:41
题目传送门
题目大意:
定义S(N) 为数字N每个位上数字的和。再给两个数a,b,求最小的正整数n,使得 a×S(n)=b×S(2n)
思路在代码中会详细解说,请看代码
#include<cstdio>#include<algorithm>#include<cstring>using namespace std;int ans[100];int tot;int gcd(int n,int m){ return m==0?n:gcd(m,n%m);}int main(){ int T; scanf("%d",&T); while(T--) { tot=0; int a,b; scanf("%d%d",&a,&b); /* 题目要求是否存在 a*s(k)=b*s(2*k)的最小 k s(k)代表k的每个数的和,比如 s(152)=1+5+2=8; 怎样弄呢?首先,我们知道 s(k)*2 和 s(2*k) 并不一定相等 它们有什么关系没?我们知道当 k 的每个数都是<5 那么 2*k 的每个数都是 k 每个数的两倍,因为没有进位 所以有 s(k)*2=s(2*k) 那么当 k 存在 >=5 的数呢? 首先 <5 的数是不是关系已经确 定 我们再来确定 >=5 的数的关系,假如只有一个数组成的数 a >=5,有s(a)=a 那么 s(2*a)=1+(2*a)%10=1+2*a-10=2*a-9(10<=2*a<=18,所以是-10) 一个数 >=5 当然也可以等价于多个数 >=5的情况 ,所以设 >=5的个数为 len 有: a*s(k)=b*s(2*k)=b*(s(k)*2-9*len) =>len/s(k)=(2*b-a)/9*b 再看下面代码 */ int m=2*b-a; int n=9*b; if(m<0||5*m>n) { printf("0\n"); continue; } /* m=2*b-a,相当于 len 1.m<0, s(k)即n=9*b是一定>0 ,但是>=5的数的个数不可能是负数 所以此情况不存在 2.m相当于 k 中 >=5的数的个数,n相当于 k 的 每个数的和,所以s(k)的min值是 5*m+((组成k的数的个数)-m )*1 是不是有 5*m<=n 所以 5*m>n 就代表不存在了 */ if(m==0) { printf("1\n"); continue; } /* 排除 k 不存在的情况,并且 k 中没有 >=5的数,你说最小的 k 是不是1? 因为m==0,s(k)可以是随便一个值,都可以满足 len/s(k)=(2*b-a)/9*b 当然选择最小的,当然是1,因为0代表不存在啊 */ int g=gcd(n,m); m/=g; n/=g; n-=m*5; /* 为什么有这个操作?因为要求最小的k,举个例子 k=55555, 有s(55555)=25,len=5,所以 len/s(k)=5/25=m/n; 所以5*b=25*a,所以b=5*a, 所以 a*s(55555)=b*s(111110)=5*a*s(111110) 但是操作 m/=g n/=g 后 len/5=1 s(55555)/5=5 ,就是k=5 所以 a*s(5)=b*s(10) 难道不可以? 如果还不理解,就多写几个例子 */ int M; for(int i=1;i<=m;i++) { M=min(4,n); n-=M; ans[tot++]=5+M; } /* 这个操作有什么用?就是把上面的例子 k=55555 变成 k=5的过程 作用其实比较好懂,看例子 k=88888111 s(k)=43, len=5,s(k)-len*5=18; 操作后k=99997,下面的操作会 逆向输出 79999 难道s(99997) 和 s(79999) 不一样吗? 所以你应该懂了吧?就是把后面的len个数尽量变成最大值9,数的个数就会有可能变少,前面的数也有可能会变小 这样是不是会得到最小值? 当然!! */ while(n>0) { M=min(4,n); n-=M; ans[tot++]=M; } /* 后面的len个数都是9了,但是s(k)还>0,所以前面<5的数也要弄,所以从后往前填 <5的数 */ for(int i=tot-1;i>=0;i--) { printf("%d",ans[i]); } //再逆向输出 printf("\n"); } return 0;}
阅读全文
0 0
- HDU5710-Digit-Sum
- lucky sum of digit
- [projecteuler]Factorial digit sum
- Sicily 7969. Digit Sum
- HDU 5710 Digit-Sum
- HDU 5710 Digit-Sum
- Digit-Sum HDU
- HDU 5710 Digit-Sum
- UVALive6497 Digit Sum【贪心】
- cc Minimal Weighted Digit Sum
- Problem 16:Power digit sum
- Problem 20:Factorial digit sum
- Problem 16:Power digit sum
- PE 16 Power digit sum
- PE 20 Factorial digit sum
- [HDU 5710]Digit-Sum:其他
- ProjectEuler-Problem20-Factorial digit sum
- Hdu 5710 Digit-Sum【思维】
- Web23.DOM操作
- 新路程------hi3516a标准简单版i2c设备驱动
- 猫狗队列
- Navicat for MySQL触发器更新和插入操作
- Spring AOP 实现原理
- HDU5710-Digit-Sum
- 数据结构与算法设计 习题2.7题 算法分析
- VC++远程注入动态库的实现(6-3)
- webRTC+coturn穿透服务器的安装与搭建
- Unity3d Attribute 总结
- java-设计模式
- Qt的pimpl模式,和Bridge模式用法和例子
- 为什么在Library中无法使用switch-case来实现点击事件的判定??
- mysql查询条件为空则查询所有