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:\n",ii); printf("%I64d\n",tot); for (i=1;i<=tot-1;i++) printf("%I64d ",ans[i]); if (tot) printf("%I64d\n",ans[tot]); } }