原题链接:蓝桥杯2017年第八届真题-分巧克力
解题思路:
【思路一】枚举每个小巧克力的边长,并把该边长下共有几个小巧克力映射到该边长,用数组实现。然后二分查找小巧克力的个数,再根据映射得到边长。 !超时!枚举每个边长并计算该边长下小巧克力的数目,数据太大了。男票提供了思路二!
【思路二】二分查找符合条件的边长,条件用ok()函数来判断。
注意事项:
参考代码:
【思路一代码】
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn = 1e+5 + 10; //int Bc2num[6] = {5,4,3,2,1,0}; int Bc2num[maxn],H[maxn],W[maxn]; int n, k, Max = -1; int lower_bound(int left, int right, int x){ int mid; while(left < right){ mid = (left + right) / 2; if(Bc2num[mid] <= x){ right = mid; }else{ left = mid + 1; } } return left; } int main(void){ scanf("%d%d",&n,&k); memset(Bc2num,0,sizeof(Bc2num)); memset(H,0,sizeof(H)); memset(W,0,sizeof(W)); for(int i = 1; i <= n; i++){ scanf("%d%d", &H[i], &W[i]); if(Max < max(H[i], W[i])){ Max = max(H[i], W[i]); } } for(int i = 1; i <= Max; i++){ int num = 0; for(int j = 1; j <= n; j++){ num += (H[j]/i) * (W[j]/i); } Bc2num[i] = num; } // for(int i = 0; i <= 5; i++){ // // printf("%d ",Bc2num[i]); // } int ans = lower_bound(0, Max, k); printf("%d",ans-1); // int ans = lower_bound(0, 5, 1); // printf("%d",ans); return 0; }
【思路二代码】
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int maxn = 1e+5 + 10; int H[maxn],W[maxn]; int n, k, Max = -1; int l = 1,m,r; int ans = 1; bool ok(int m){ int sum = 0; for(int i = 1; i <= n; i++){ sum += (H[i]/m) * (W[i]/m); } if(sum >= k) return true; else return false; } int main(void){ scanf("%d%d",&n,&k); memset(H,0,sizeof(H)); memset(W,0,sizeof(W)); for(int i = 1; i <= n; i++){ scanf("%d%d", &H[i], &W[i]); if(Max < max(H[i], W[i])){ Max = max(H[i], W[i]); } } r = Max; while(l <= r){ m = (l + r) / 2; if(ok(m)){ ans = m; l = m + 1; }else{ r = m - 1; } } printf("%d",ans); return 0; }
【官答】
#include<stdio.h> #define N 100000 bool ok(int m); int a,b; int H[N],W[N]; int main() { int c,l=1,max=0,r,ans=1; long long m; scanf("%d %d",&a,&b); for(c=0;c<a;c++) { scanf("%d %d",&W[c],&H[c]); if(max<=W[c]) max=W[c]; if(max<=H[c]) max=H[c]; } r=max; while(l<=r) { int m=(l+r)/2; if(ok(m))ans=m,l=m+1; else r=m-1; } printf("%d",ans); return 0; } bool ok(int m) { long long c = 0; for(int i = 0; i < a; i++) { c+=(long long)(H[i]/m)*(W[i]/m); } if(c>=b) return true; return false; }
0.0分
5 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复