第一题:生日蛋糕
题解:这题是蛋糕结构是一层一层的,估计很多人很快就能想到是dfs,但是这题的难想的点在于
你每层的状态该怎么去确定,你怎么来确定每层的半径和高度是多少,一开始我也不知很理解,直到在网上看到了一篇大佬的博客才让我茅塞顿开,我干嘛非要确定呢,全用最小的不就好了,因此我们要写出每层的最小的体积和面积,然后用前缀和累加起来,然后三个剪枝(代码里有注释)减少运算,就可以愉快的AC了
#include<iostream>
#include<cstring>
#include<cstdio>
#include <queue>
#include<math.h>
using namespace std;
int n,m;
int sums[16];
int sumv[16];
int sum=0x7fffffff;//记录最小的值 void dfs(int t,int s,int v,int r,int h)
{if(t==0){if(s<sum&&v==n){sum=s;}return ;}if(s+sums[t]>sum)//第一个剪枝,你目前的面积,加上上面层的最小的面积>已知面积,可以直接跳过return ;if(v+sumv[t]>n)//第二个剪枝,你目前的体积,加上上面层的最小的体积>要求的体积,可以直接跳过return ;if(s+2*(n-v)/r>sum)//第三个剪枝,你把所有体积都做成一层蛋糕,如果面积>已知面积,跳过return ;for(int i=r-1;i>=t;i--){if(t==m)s=i*i;int h1=min(h-1,(n-v-sumv[t-1])/(i*i));for(int j=h1;j>=t;j--){dfs(t-1,s+2*i*j,v+i*i*j,i,j);}}return ;
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){sumv[i]+=sumv[i-1]+i*i*i;sums[i]+=sums[i-1]+2*i*i;}dfs(m,0,0,sqrt((double)n)+1,n);if(sum==0x7fffffff){printf("0");return 0;}printf("%d",sum);return 0;
}
第二题:速算24
题解:这题一开始也卡了我好久,我一直不明白哪里错了,后面问了学长,但是还是自己想出来为什么错了,因为有可能二三进行运算,这样的话,就会漏掉情况,所以一开始一直过不了,然后写出来了,还用到了全排列函数(不会的可以去了解一下),AC代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;char s[5]={0};
int num[5]={0};
int flag=0;void dfs(int sum,int count,int nextt)
{if(flag==1)return ;if(count==3){if(sum+nextt==24)flag=1;if(sum-nextt==24)flag=1;if(sum*nextt==24)flag=1;if(nextt!=0&&sum%nextt==0&&sum/nextt==24)flag=1;return ;}dfs(sum+nextt,count+1,num[count+1]);dfs(sum-nextt,count+1,num[count+1]);dfs(sum*nextt,count+1,num[count+1]);if(nextt!=0&&sum%nextt==0){dfs(sum/nextt,count+1,num[count+1]);}dfs(sum,count+1,nextt+num[count+1]);dfs(sum,count+1,nextt-num[count+1]);dfs(sum,count+1,nextt*num[count+1]);if(num[count+1]!=0&&nextt%num[count+1]==0){dfs(sum,count+1,nextt/num[count+1]);}
// dfs(sum+nextt,count+1,num[count+1]);
// dfs(sum-nextt,count+1,num[count+1]);
// dfs(sum*nextt,count+1,num[count+1]);
// if(sum%nextt==0&&nextt!=0)
// {
// dfs(sum/nextt,count+1,num[count+1]);
// }
// dfs(sum,count+1,nextt+num[count+1]);
// dfs(sum,count+1,nextt-num[count+1]);
// dfs(sum,count+1,nextt*num[count+1]);
// if(nextt%num[count+1]==0&&num[count+1]!=0)
// {
// dfs(sum,count+1,nextt/num[count+1]);
// }
}int main()
{while (~scanf("%s", s)){flag = 0;if (strlen(s) == 2)num[0] = 10;else{if (s[0] == 'A')num[0] = 1;else if (s[0] == 'J')num[0] = 11;else if (s[0] == 'Q')num[0] = 12;else if (s[0] == 'K')num[0] = 13;elsenum[0] = s[0] - '0';}for (int i = 1; i < 4; i++){scanf("%s", s);if (strlen(s) == 2)num[i] = 10;else{if (s[0] == 'A')num[i] = 1;else if (s[0] == 'J')num[i] = 11;else if (s[0] == 'Q')num[i] = 12;else if (s[0] == 'K')num[i] = 13;elsenum[i] = s[0] - '0';}}flag=0;sort(num,num+4);do{dfs(num[0],1,num[1]);}while(next_permutation(num,num+4)&&flag==0);if (flag == 1)printf("Yes\n");elseprintf("No\n");}return 0;
}