3 solutions

  • 1
    @ 2025-3-11 13:08:33

    可以理解为把坑填平

    填坑消耗的万能卡<=目标高度(4)时可以由经过平移变化,使每一层至多有一张万能卡

    样例

    4 5
    2 3 4 5
    
       样例     填坑后    平移变化
    0 0 0 1   0 0 0 1    0 0 0 1
    0 0 1 1   x x 1 1    x 1 1 1
    0 1 1 1-->x 1 1 1--->x 1 1 1
    1 1 1 1   1 1 1 1    x 1 1 1
    1 1 1 1   1 1 1 1    1 1 1 1
    
    #include <bits/stdc++.h>
    using namespace std;
    #define int long long 
    int n, m;
    bool check(int x,vector<int>&a){
    	int diff = 0;//diff为消耗的万能卡,图中的x
    	for (int i = 1; i <= n; i++) {
    		if (a[i] < x)diff += x - a[i];
    		if (diff > m || diff > x){
    			return false;
    		}
    	}
    	return true;
    }
    
    
    signed main() {
    	cin >> n >> m;
    	vector<int>num(n+1);
    	for (int i = 1; i <= n; i++)cin >> num[i];
    	sort(num.begin() + 1, num.end());
    	int l = num[1], r = num[n];
    
    	//对目标高度二分
    	while (l < r) {
    		int mid = l + (r - l + 1) / 2;
    		if (check(mid, num))l = mid;
    		else r = mid - 1;
    	}
    	cout << l;
    	return 0;
    }
    
    • 1
      @ 2025-3-10 13:01:53

      样例解释:

      4 5
      2 3 4 5
      

      达成四种的方法:

      {1,r,3,4} , {1,r,3,4} , {r,2,3,4} , {r,2,3,4}

      边界为什么是 c[1] + c[2] ? 进行排序后,c[1] , c[2] 则是俩个最小的数据,像上列数据一样,各自尽可能的和 r 卡组合,这样才会尽可能的将套数变多

      • 1
        @ 2025-3-9 20:51:30
        #include<iostream>
        #include<algorithm>
        
        using namespace std;
        int n,m,c[55];
        
        bool check(int t)
        {
            int r = min( m - t + c[1], c[1] );//min(m-(t-c[1]) , t-(t-c[1]));
            if(r < 0)return flase;
            for(int i = 2 ;i <= n;i++)
            {
                
                 if( r < t - c[i])
                {
                    return false;
                }
                r -= t - c[i];
              if( c[i] >= t )break;
            }
            return true;
        }
        int main()
        {
            cin>>n>>m;
            for(int i = 1;i <= n;i++)
            {
                scanf("%d",&c[i]);
            }
            sort(c + 1,c + n + 1);//进行排序
            int l =  c[1];
            int r = c[1] + c[2];
            while(l < r)//以套数作为总的边界
            {
                int mid = l + r + 1 >>1;
                if ( check(mid)== false )r = mid - 1;
                else l = mid;
            }
            cout<<l;
            return 0;
        }
        
        • 1

        Information

        ID
        7013
        Time
        1000ms
        Memory
        256MiB
        Difficulty
        4
        Tags
        (None)
        # Submissions
        174
        Accepted
        11
        Uploaded By