题目链接:https://vjudge.net/problem/CodeChef-FORESTGA
题解:
现场赛。拿到这题很快就知道是二分,但是一直wa,怎么修改也wa,后来又换了种错误的思路,最后还是觉得二分是正确的,但还是wa。人生,就是在这些瞬间被怀疑的……
结束后,才发现,test()的时候溢出了。应该把判断放在循环里面,如果达到要求的,就立刻返回。因为达到要求后,后面的运算都是多余的。
反思:
在某些判断中,如果达到要求后,就立刻执行。不要等所有操作完成后,再执行,因为可能出现意想不到的结果。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <cmath> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 #define ms(a,b) memset((a),(b),sizeof((a))) 13 //#define LOCAL 14 using namespace std; 15 typedef long long LL; 16 const int INF = 2e9; 17 const LL LNF = 9e18; 18 const int mod = 1e9+7; 19 const int maxn = 1e5+10; 20 const double pi = acos(-1.0); 21 22 LL n,w, li; 23 int h[maxn], r[maxn]; 24 25 bool test(LL m) 26 { 27 LL s = 0; 28 for(int i = 1; i<=n; i++) 29 { 30 LL t = 1LL*h[i]+1LL*m*r[i]; 31 if(t<li) continue; 32 s += t; 33 if(s>=w) 34 return 1; 35 } 36 return 0; 37 } 38 39 //bool test(LL m) 40 //{ 41 // LL s = 0; 42 // for(int i = 1; i<=n; i++) 43 // { 44 // LL t = 1LL*h[i]+1LL*m*r[i]; 45 // if(t<li) continue; 46 // s += t; 47 // } 48 // return s>=w; //加完再判断会溢出。 49 //} 50 51 52 int main() 53 { 54 scanf("%lld%lld%lld",&n,&w,&li); 55 for(int i = 1; i<=n; i++) 56 scanf("%d%d",&h[i],&r[i]); 57 58 LL l = 0, r = 1e18; 59 while(l<r) 60 { 61 LL m = (l+r)>>1; 62 if(test(m)) 63 r = m; 64 else 65 l = m + 1; 66 } 67 printf("%lld ",r); 68 }