天天看点

HDU5109 Alexandra and A*B Problem(数学题)Alexandra and A*B Problem

Alexandra and A*B Problem

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5109

解题思路:

BestCoder官方题解:

最后的A*B应该是xSy的形式,其中y可以为空,并且如果S不以0开头那么x也可以为空。
首先枚举y的长度。在y的长度确定之后,显然x应该越小越好。所以从小到大枚举x。设S的长度为p,y的长度为q,那么可以列方程:
  
   ((x∗10p+S)∗10q+y)modA=0
  。解出y以后,如果
  
   y<10q
  那么解合法。
容易证明,我们只需从0(或1,如果S以0开头)到A枚举x,那么所有的解一定会被枚举到。对于q=0的情况,x的长度不会超过4,所以y的长度也只需要枚举到4就可以了。
对于所有枚举出的长度算出的答案取最优解即可。

当然也可以用其他的枚举方法,只要枚举量大概是1万左右的数量级都是可以的。      

其实:正如题解所言,当s[0]=='0'时,x的范围为1~a-1;其他,x的范围就是0~a-1。然后在枚举y的长度。因为((x*10^ls+s)*10^ly+y)%a=0 

所以a-((x*10^ls+s)*10^ly)%a的值一定为y的值。然后再取最小值,即为所求。

AC代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;

typedef long long ll;

int main(){
    int a,b;
    char s[10];
    while(scanf("%d%s",&a,s)!=EOF){
        int i,l = strlen(s),pp = 1,yl;
        ll x,ss,ans = -1,tt;
        if(s[0]=='0' && l==1){
            printf("0\n");
            continue;
        }
        for(i = 1; i <= l; i++)
            pp *= 10;
        sscanf(s,"%I64d",&ss);
        for(yl = 1; yl <= 10000; yl *= 10){
            for(x = (s[0]=='0'); x < a; x++){
                tt = (x*pp+ss)*yl;
                int mod = (a-tt%a)%a;
                if (mod < yl){
                    tt += mod;
                    if(ans < 0 || tt < ans)
                        ans=tt;
                }
            }
        }
        printf("%lld\n",ans/a);
    }
    return 0;
}