• 【ZOJ 4062】Plants vs. Zombies


    【链接】 我是链接,点我呀:)
    【题意】

    【题解】

    二分最后的最大抵御值mid。 然后对于每个蘑菇。 都能算出来它要浇水几次mid/a[i](上取整) 然后如果第i个蘑菇没浇水达到要求次数。 就在i和i+1之间来回走动(注意改变第i+1个蘑菇的状态) 直到满足每个蘑菇的浇水需求为止。 注意如果到了最后一个蘑菇所在的位置之后。 如果这个蘑菇已经不需要浇水了 那么就没有必要来到第n个位置。直接在n-1位置停下来就ok了

    【代码】

    #include <bits/stdc++.h>
    #define ll long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    using namespace std;
    
    const int N = 1e5;
    
    int n;
    ll m;
    ll a[N+10];
    ll b[N+10];
    
    bool ok(ll mid){
    	if (mid==0) return true;
    	for (int i = 1;i <= n;i++){
    	 	b[i] = mid/a[i];
    	 	if (mid%a[i]!=0) b[i]++;
     	}
     	ll cur = m;
     	for (int i = 1;i <= n;i++){
     	 	if (i==n && b[i]<=0) return true;
     	 	if (cur<=0) return false;
     	 	cur--;
     	 	if(b[i]>=1){
     	 	 	b[i]--;
     	 	 	cur-=(b[i]*2);
     	 	 	b[i+1]-=b[i];
     	 	 	if (cur<0) return false;
     	 	}
     	}
     	return true;
    }
    
    int main(){
    //	freopen("rush.txt","r",stdin);
    	int T;
    	scanf("%d",&T);
    	while (T--){
    		scanf("%d%lld",&n,&m);
    		for (int i = 1;i <= n;i++) scanf("%lld",&a[i]);
    		ll l = 0,r = 1e17,temp = -1;
    		while (l<=r){
    			ll mid = (l+r)>>1;
    //			printf("%lld
    ",mid);
    			if (ok(mid)){
    			 	temp = mid;
    			 	l = mid + 1;
    			}else{
    				r = mid - 1;
    			}
    		}
    		printf("%lld
    ",temp);
    	}
    
     	return 0;
    }
    
  • 相关阅读:
    android面试之怎么把图片变成圆形
    android面试之contentProvider获取联系人
    Android面试之assets和aw文件的使用
    Android设计模式之面试
    Activity、Window、View的关系
    ViewPager的简单用法
    补间动画
    帧动画
    android系统的样式和主题
    C++的三种继承方式简述
  • 原文地址:https://www.cnblogs.com/AWCXV/p/9920442.html
Copyright © 2020-2023  润新知