2 条题解

  • 1
    @ 2026-5-31 13:56:26

    我的题解更好看,看我的

    考场睡大觉,考完净在这懊悔,二分写错了


    正言

    这题弄清楚题意后,很容易想到:二分查找满足 Hi+前缀和最小值>0H_i + 前缀和最小值 >0 的最小 HiH_i

    注意一个坑点:输入数据中H可取0,没注意到这点只有40分

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e5+9;
    const int inf = 1.01e9+9;
    using pii = pair<int,int>; 
    using ll = long long;
    const ll INF = 1.01e18+9;
    int h[N],m[N];
    vector<int>d[N];
    int ef(ll k,int n){
    	int l = 1,r = n+1;
    	while(l<r){
    		int mid = l+r>>1;
    		if(h[mid] > k)r = mid;
    		else l = mid+1;
    	}
    	return l;
    } 
    void solve(){
    	int n,t;cin>>n>>t;
    	for(int i =1;i<=n;i++){
    	     cin>>h[i];if(h[i] == 0)h[i] = -inf;
        }
    	sort(h+1,h+1+n);
    	for(int i =1;i<=t;i++) cin>>m[i];
    	for(int i = 1;i<=t;i++){
    		d[i].push_back(-inf);
    		for(int j =1;j<=m[i];j++){
    			int a;cin>>a;
    			d[i].push_back(a);
    		}
    	}
    	for(int i =1;i<=t;i++){
    		ll min_num = INF,now = 0;
    		for(int j =1;j<=m[i];j++){
    			now += d[i][j],min_num = min(min_num,now);
    		}
    		
    		int ans = ef(-min_num,n);
    //		if(h[ans] == 0)cout<<"r"<<'\n';
    		if(ans <= n)cout<<h[ans]<<'\n';
    		else cout<<-1<<'\n';
    	}
    	
    }
    int main(){
    	cin.tie(0) ->sync_with_stdio(false);
    	freopen("rush.in", "r", stdin);
      	freopen("rush.out", "w", stdout);
    	solve();
    	return 0; 
    } 
    
    /*
    3 3
    200 120 1
    3 3 3
    -10 -10 -100
    -10 -10 -10
    -10 -10 -100
    
    3 3
    2 0 0
    1 1 1
    -1
    -1
    -1
    
    
    */
    
    • -1
      @ 2026-5-31 13:11:59

      ``#include <bits/stdc++.h> using namespace std;

      //TD //有点小难的Td //题意大致为给定生命和路,每个方格的权判断能否通过 //输入输出不解释 //关键在于每条路,记now为总的前缀和优化未初始化前缀和 //那么记mini为最小的当前路的当前位置的前缀和 // 如果mini+最大的生命<=0,那么无法通过 //直接输出-1然后continue //否则,在生命数组二分 //如果生命[mid]+mini<=0,即这个生命不合法,则l=mid+1 //合法则r=mid //取第一个大于等于合法答案的 //那么让l动,让r可越界 //最后输出生命[l]就通过了

      const int N =1e5+9;

      int n,T; long long jia[N]; int lu[N]; int main(){

      freopen("rush.in", "r", stdin);
      freopen("rush.out", "w", stdout);
      ios::sync_with_stdio(false);
      cin.tie(0);
      cout.tie(0);
      
      cin>>n>>T;
      for(int i=1;i<=n;i++)cin>>jia[i];
      sort(jia+1,jia+n+1);//思路,排序优化前缀和二分 
      for(int i=1;i<=T;i++)cin>>lu[i];
      
      long long mi;
      
      
      
      for(int i=1;i<=T;i++){
      	
      	long long mini=0;
      	long long now=0;//我懂问题出在哪了,sum数组没初始化数据错误 
      	for(int j=1;j<=lu[i];j++){//所以只需创建一个now? 
      		cin>>mi;
      		now+=mi;
      		mini=min(mini,now);
      	}
      	
      	
      	
      	if((mini+jia[n])<=0){
      		cout<<-1<<endl;
      		continue;
      	}
      	int l=1,r=n+1;
      	while(l<r){
      		int mid=(l+r)>>1;
      		if((mini+jia[mid])<=0)l=mid+1;
      		else r=mid;
      	}
      	
      	cout<< jia[l]<<endl;
      }
      return 0;
      

      } ``

      • 1

      信息

      ID
      142
      时间
      1000ms
      内存
      256MiB
      难度
      3
      标签
      递交数
      80
      已通过
      9
      上传者