[ZOJ 3360] Stranger Calendar II [迭代加深]

来源:互联网 发布:移动数据流量标准资费 编辑:程序博客网 时间:2024/06/02 07:31

给定一个分数x,求一个长度不超过5的数列,使得x=1/a1-1/(a1*a2)+1/(a1*a2*a3)...或x=1-1/a1+1/(a1*a2)-1/(a1*a2*a3)...

如果存在多组解,让数列的长度尽可能的小,在数列长度一定的情况下输出任意一组可行解均可。如果不存在这样的长度小于等于5的数列,则输出Too complex

迭代加深,枚举数列长度,然后搜索即可。

为了防止double丢精度,尽量使用整数运算。

#include <cstdio>long long a,b;long long ans[6];long long gcd(long long a,long long b) {long long c=a%b;while (c) {a=b;b=c;c=a%b;}return b;}bool lessEqualThan(long long a,long long b,long long c,long long d) {long long tmpb=b/gcd(b,d),tmpd=d/gcd(b,d);return a*tmpd<=c*tmpb;}bool dfs(long long cura,long long curb,int n,bool plus) {if (cura*b==curb*a) return true;if (n==0) return false;if (plus) {for (int k=2;lessEqualThan(a,b,cura*k+1,curb*k);k++) {ans[n]=k;if (dfs(cura*k+1,curb*k,n-1,false)) return true;}} else {for (int k=2;lessEqualThan(cura*k-1,curb*k,a,b);k++) {ans[n]=k;if (dfs(cura*k-1,curb*k,n-1,true)) return true;}}return false;}int main() {int t;scanf("%d",&t);while (t--) {scanf("%lld%lld",&a,&b);int n=1;while (n<6) {if (dfs(0,1,n,true)) break;if (dfs(1,1,n,false)) break;n++;}if (n==6) printf("Too complex\n");else {printf("%lld",ans[n]);for (int i=n-1;i>0;i--) printf(" %lld",ans[i]);printf("\n");}}return 0;}


0 0
原创粉丝点击