AcWing 1209. 带分数
考察:dfs
日常感慨自己的rz,自己想的思路和y总一样,也是dfs嵌套.但是代码不会实现而且想的是4个dfs嵌套.醉了
自己的思路:
N = a+b/c,a b c的位数需要dfs枚举,确定位数后dfs a,b,c在最后c进行ans++.思路是4个嵌套但是不会剪枝555.而且感觉真的是极其复杂
暴力思路:
完全没必要枚举位数.9个数字不能重复,相当于a,b,c在9个数字里各取数字.我们可以将9个数字铺展开.设置两个隔板.前面的为a,中间b,最后c.那么需要变动的不是a,b,c而是9个数字的顺序.直接用STL的全排列即可
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 typedef long long ll; 7 const int N = 11; 8 int a[N]; 9 ll calc(int st,int ed) 10 { 11 ll res = 0; 12 for(int i=st;i<=ed;i++) 13 res = res*10+a[i]; 14 return res; 15 } 16 int main() 17 { 18 int ans = 0,n; 19 scanf("%d",&n); 20 for(int i=1;i<10;i++) a[i] = i; 21 do{ 22 ll x,y,z; 23 for(int i=1;i<8;i++) 24 { 25 x = calc(1,i); 26 if(x>n) continue; 27 for(int j=i+1;j<9;j++) 28 { 29 y = calc(i+1,j); 30 z = calc(j+1,9); 31 if(y/z>n) continue; 32 if(y%z!=0) continue; 33 if(x+y/z==n) ans++; 34 } 35 } 36 }while(next_permutation(a+1,a+10)); 37 printf("%d\n",ans); 38 return 0; 39 }
Y总思路:
dfs嵌套,但同样没必要枚举位数,直接枚举a,c.这是在暴力的行为上进行优化.因为b/c存在小数.所以等式两边*c,这样假设已经枚举了a,c.那么b就已知了: b = n*c-a*c
因此直接dfs枚举a与c即可.在dfs完a后再dfs c,在枚举每一个c的时候判断即可
dfs嵌套一定要分清哪些部分是枚举,哪些部分是继续dfs,哪些部分是判断是否回溯.
判断是否回溯不一定要和继续dfs(或者检验答案)写在一起
坑点:
n*c可能溢出
b要判断是否为0
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 typedef long long ll; 7 const int N = 13; 8 int n,ans; 9 bool st[N],backup[N]; 10 bool check(int a,int c) 11 { 12 ll b = (ll)c*n-(ll)a*c; 13 if(!b) return false; 14 memcpy(backup,st,sizeof st); 15 while(b) 16 { 17 if(b%10==0||backup[b%10]) return false; 18 backup[b%10] = 1; 19 b/=10; 20 } 21 for(int i=1;i<=9;i++) if(!backup[i]) return false; 22 return true; 23 } 24 void dfs_c(int k,int a,int c) 25 { 26 if(k==n) return;//递归终止条件 27 if(c&&check(a,c)) ans++; 28 for(int i=1;i<=9;i++)//枚举C 29 { 30 if(!st[i]) 31 { 32 st[i] = 1; 33 dfs_c(k+1,a,c*10+i); 34 st[i] = 0; 35 } 36 } 37 } 38 void dfs_a(int k,int now) 39 { 40 if(now>n||k==n) return; 41 if(now) dfs_c(k,now,0);//用了几个数字,a,c 42 for(int i=1;i<=9;i++)//for循环里是枚举a 43 { 44 if(!st[i]) 45 { 46 st[i] = 1; 47 dfs_a(k+1,now*10+i);//枚举每一个a 48 st[i] = 0; 49 } 50 } 51 } 52 int main() 53 { 54 scanf("%d",&n); 55 dfs_a(0,0); 56 printf("%d\n",ans); 57 return 0; 58 }