hdu5255 魔法因子

  题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5255

  首先先预处理出一个p,使得p*因子X等于一个整数,且p最小,设q=p*X。

  则题目则可以看成存在一个r,使得p*r和q*r,数字的首位和末位交换位置,而其他位置上的数字恰好不变。

  那么怎么求这个r呢,考虑到abs(q*r-p*r)=abs(q-p)*r,且abs(q*r-p*r)=X99...99Y,X+Y=9,且中间数字全是9,由于只要统计10位数以内的答案,因此去枚举这种形式的数字,且判断q*r和p*r是否可行。

  读入的时候没考虑到精度问题直接*10^6导致wa了10+次,因此最好用字符串读入。

  代码:

#include<cstdio>
#include<algorithm>
#include<map>
#include<cstring>
#include<vector>
#include<cmath>
#include<string>
#define N 2000010
#define M 1000
using namespace std;
double n;
long long a,b,z,pp,qq,ans[N],P,p,q,o,k,tot,i,j,l;
long long gcd(long long a,long long b)
{
    if (b==0) return a;
    return gcd(b,a%b);
}
int check(long long p,long long q)
{
    if (p==0) return 0;
    if (p>=P) return 0;
    long long a,b,c=1,pp;
    a=p%10;
    pp=p;
    while (pp)
    {
        b=pp%10;
        pp=pp/10;
        c=c*10;
    }
    c=c/10;
    p=p-a+b-b*c+a*c;
    if (p==q) return 1;return 0;
}
int main()
{
    int test,ii;
    P=1000000;
    P=P*10000;
    scanf("%d",&test);
    for (ii=1;ii<=test;ii++)
    {
    tot=0;
    scanf("%lf",&n);
    p=(n+0.0000005)*1000000;
    q=p/gcd(p,1000000);
    p=1000000/gcd(p,1000000);
    o=abs(p-q);
  
    b=10;a=0;
    for (k=0;k<=8;k++)
    {
    for (i=0;i<=9;i++)
    for (j=0;j<=9;j++)
    {
        z=b*i+a*10+j;
        if (z%o==0) 
        {
            z=z/o;
            pp=p*z;qq=q*z;
            if (check(pp,qq))
            {
                tot++;
                ans[tot]=pp;
            }
        }
    }
    a=a*10+9;
    b=b*10;
    }
    sort(ans+1,ans+1+tot);
    j=0;ans[0]=-1;
    for (i=1;i<=tot;i++)
    if (ans[i]!=ans[i-1])
    {
        j++;ans[j]=ans[i];
    }
    tot=j;
    printf("Case #%d:
",ii);
    printf("%I64d
",tot);
    for (i=1;i<=tot-1;i++)
    printf("%I64d ",ans[i]);
    if (tot)
    printf("%I64d
",ans[tot]);
    }
}
原文地址:https://www.cnblogs.com/fzmh/p/4553156.html