HDU 5710 Digit-Sum 数学杂题

原题见HDU 5710

题意:定义 S(N) N 的数位之和,给出一对a,b(0<a,b<101),求是否存在 n 满足

a×S(n)=b×S(2n)

分析: S(n)S(2n) 的关系如何?

对于n中的任何一个数位x,若x为0-4,则因为没有进位,所以在S(2n)中贡献为2x;若x为5-9,则由于其超过10,在S(2n)中贡献为2x-10+1.这里不用担心因为进位会使得高位又满10进位,事实上前一位最多为2*9=18或者是单纯的8,不可能出现9.

x位数 S(n) S(2n)
0~4x2x
5~9Lx2x-9

可见只有5~9的位数使 S(n)S(2n) 有了差异,即 S(2n)=2S(n)9L ,代入原式, S(n)S

a×S=b×(2S9L)
(2ba)S=9bL

1. a=2b,则L=0,S为任意值。可得最小的n=1;
2. a>2b,则L<0,矛盾!则无满足的n,输出0;
3. a<2b, S=9bL2ba5L (至少有L个5),即必须满足 b5a ,否则无满足的n,输出0。

继续讨论上述第三种情况,由于分母为2b-a,L周期性地使得右边式子可以整除,现在只要求出最小的L,枚举范围从1到2b-a必定会有满足的L。
得到一组满足的(L,S),构造最小的n。首先先要在后L位塞满5,剩下的(S-5L)开始从个位到高位塞4,直到塞完为止。

讨论:L与n的关系?

问题来了,既然L可以取多个,怎么保证最小的L使得n最小?
假设L’=L+x, S=9b(L+x)2ba
原来的位数(大约)是(除以4的地方应该加个向上取整)

9bL(2ba)9L4+L

现在的位数是
9b(L+x)(2ba)9(L+x)4+(L+x)

后面减前面,差值是
9bx(2ba)9x4+x=5ab4(2ba)x
又有条件 b5a ,则这个差值大于等于0.位数大的数肯定比原来大了。所以最小的L可以得到最小的n.

附代码

/*--------------------------------------------
 * File Name: HDU 5710
 * Author: Danliwoo
 * Mail: Danliwoo@outlook.com
 * Created Time: 2016-07-05 17:09:58
--------------------------------------------*/

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
using namespace std;
#define N 1000
int ans[N], a, b;
void solve(){
    if(a == 2*b){
        printf("1\n");
        return;
    }
    if(a > 2*b || 5*a < b){
        printf("0\n");
        return;
    }
    int L, S;
    for(L = 1;L < 1000;L++){
        S = 9*b*L/(2*b-a);
        if((2*b-a)*S == 9*b*L)
            break;
    }
    memset(ans, 0, sizeof(ans));
    for(int i = 0;i < L;i++)
        ans[i] = 5;
    S -= L*5;
    int len;
    for(int i = 0;;i++){
        if(S > 4){
            ans[i] += 4;
            S -= 4;
        } else {
            ans[i] += S;
            S = 0;
            len = i+1;
            break;
        }
    }
    len = max(len, L);
    for(int i = len-1;i >= 0;i--)
        printf("%d", ans[i]);
    printf("\n");
}
int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        scanf("%d%d", &a, &b);
        solve();
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值