每日一题 day62 打卡
Analysis
这道题一看感觉很像搜索,但是每次枚举x∈(1,10000000)作为分母显然太蠢了。
所以我们要想办法优化代码。
优化一:迭代加深
优化二:
我们确定了搜索方式,现在就要确定搜索的上下界。
因为现在搜索的分数一定要比剩下的值小,于是有:
1/i<x/y
上界满足 y<xi
设还有k个分数,因为枚举的分母是单调递增的,所以分数的值是单调递减的,可得后k个分数的值严格小于k/i,而这个值一定要比当前剩下的值大,
于是有:
k/i>x/y
下界满足 ky>xi
优化想好了之后就可以安心码代码~~~
注意:一些细节在代码中有注释
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define int long long 6 #define INF 2147483647 7 #define maxn 100000+10 8 #define rep(i,s,e) for(register int i=s;i<=e;++i) 9 #define dwn(i,s,e) for(register int i=s;i>=e;--i) 10 using namespace std; 11 inline int read() 12 { 13 int x=0,f=1; 14 char c=getchar(); 15 while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();} 16 while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();} 17 return f*x; 18 } 19 void write(int x) 20 { 21 if(x<0) {putchar('-'); x=-x;} 22 if(x>9) write(x/10); 23 putchar(x%10+'0'); 24 } 25 int a,b; 26 int t,len; 27 int s[maxn],ans[maxn]; 28 inline int calc(int x,int y) 29 { 30 rep(i,2,INF) 31 if(x*i>y) 32 return i; 33 } 34 bool dfs(int rest,int x,int y)//因为要方便判断枚举的长度可不可以,所以选择bool类型的搜索 35 { 36 if(rest==1) 37 { 38 if(x==1&&y>s[t]&&(len==0||y<ans[len])) 39 { 40 len=++t; 41 s[t]=y; 42 rep(i,1,t) ans[i]=s[i]; 43 --t; 44 return true; 45 } 46 return false; 47 } 48 bool flag=false; 49 for(register int i=max(s[t]+1,calc(x,y));rest*y>i*x;++i) 50 { 51 int now_x=x*i-y; 52 int now_y=y*i;//nx/xy=x/y-1/i; 53 int mod=__gcd(now_x,now_y); 54 now_x/=mod; 55 now_y/=mod; 56 s[++t]=i; 57 if(dfs(rest-1,now_x,now_y)==true) flag=true; 58 --t; 59 } 60 return flag; 61 } 62 signed main() 63 { 64 a=read();b=read(); 65 int mod=__gcd(a,b); 66 a/=mod; 67 b/=mod; 68 if(a==1) {write(b); return 0;} 69 s[0]=1; 70 rep(i,2,INF) 71 { 72 t=0; 73 if(dfs(i,a,b)==true) 74 { 75 rep(j,1,len) 76 { 77 write(ans[j]); 78 putchar(' '); 79 } 80 break;//第一次搜到的答案一定是最优 81 } 82 } 83 return 0; 84 }
如有失误请各位大佬斧正(反正我不认识斧正是什么意思)