zoukankan      html  css  js  c++  java
  • Social Distance(贪心+构造)

    传送门

    很有意思的一道题

    • 既然要求最大能放入多少人,那么也就暗示从左往右(或从右往左)开始,按照顺序,能放就放,这样就能保证最优。

    因此,问题就可以归结到如何构造上了

    那么该如何构造呢?

    由于数据很大,结合经验基本可以确定是O(N)的时间复杂度,因此就要思考如何处理才能使得操作具有O(N)的时间复杂度

    我的思路

    先用一个优先队列(小根堆)存入每个值为1的点,这样所有为1的点就按照顺序排列了,还有一点非常重要的是:

    • 最后再放入一个很大的数字
      再然后就是判断了,如果符合条件就跳到下一个符合条件的地方并且答案+1,即:i + k + 1
      如果不符合就跳到下一个符合条件的地方
    #include <iostream>
    #include <string>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    
    const int N = 2e5 + 10;
    int a[N];
    
    void solve(){
    	priority_queue<int, vector<int>, greater<int> > pq;
    	int n, k;
    	string s;
    	cin >> n >> k;
    	cin >> s;
    	for(int i = 0; i < n; i ++)
    		if(s[i] == '1')
    			pq.push(i);
    	int size = pq.size();
    	if(!size){
    		if(n < k + 1)
    			cout << 1 << endl;
    		else{
    			if(n % (k + 1) == 0)
    				cout << n / (k + 1) << endl;
    			else
    				cout << n / (k + 1) + 1 << endl;
    		}
    		return;
    	}
    	pq.push(n + 3e5);
    	int temp = 0;
    	while(pq.size() && temp < n){
    		if(temp <= pq.top())
    			a[temp] = pq.top();
    		else{
    			pq.pop();
    			a[temp] = pq.top();
    		}
    		temp ++;
    	}
    	int ans = 0;
    	for(int i = 0; i < n; i ++){
    		if(s[i] == '1')
    			i = i + k;
    		else{
    			if(a[i] - i > k){
    				ans ++;
    				i = i + k;
    			}
    		}
    	}
    	cout << ans << endl;
    }
    int main(){
    	int t;
    	cin >> t;
    	while(t --){
    		solve();
    	}
    	return 0;
    }
    
  • 相关阅读:
    sqlServer的主键只能自增不能手动增加
    TP函数
    TP复习17
    TP复习16
    TP复习15
    TP复习14
    TP复习13
    TP复习12
    TP复习11
    TP复习10
  • 原文地址:https://www.cnblogs.com/pureayu/p/14410279.html
Copyright © 2011-2022 走看看