zoukankan      html  css  js  c++  java
  • Codeforces 521D. Shop 题解

    题目链接:D. Shop

    题目大意:洛谷


    题解:三种操作,先考虑顺序。操作 1 最先,2 其次,3 最末,证明显然。然后如果进行操作 1,那么肯定对于任意一个数只操作 1 次,并且一定赋为最大值,这也显而易见,所以我们可以将赋值操作转换为加法操作。

    对于同一个数的加法操作总是从大向小加肯定不劣,所以我们将同一个数的加法从大往小排序,这样的话每一次加法可以转换为当前数乘上一个浮点数,这样的话就转换为了操作 3。

    现在我们只有操作 3 了,从大向小排序,贪心取即可,最后将 1,2,3操作的顺序调换一下就可以了。时间复杂度(O(nlog n))

    代码:。

    #include <vector>
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    void read(int &a){
    	a=0;
    	char c=getchar();
    	while(c<'0'||c>'9'){
    		c=getchar();
    	}
    	while(c>='0'&&c<='9'){
    		a=(a<<1)+(a<<3)+(c^48);
    		c=getchar();
    	}
    }
    typedef long long ll;
    const int Maxn=100000;
    int a[Maxn+5];
    int k,n,m;
    int op[Maxn+5];
    vector<pair<int,int> > q[Maxn+5][3];
    int id[Maxn+5],len;
    vector<pair<double,int> > b;
    bool cmp(int p,int q){
    	if(op[p]==op[q]){
    		return p<q;
    	}
    	return op[p]<op[q];
    }
    int main(){
    	read(k),read(n),read(m);
    	for(int i=1;i<=k;i++){
    		read(a[i]);
    	}
    	for(int i=1;i<=n;i++){
    		read(op[i]);
    		int pos,x;
    		read(pos),read(x);
    		q[pos][op[i]-1].push_back(make_pair(x,i));
    	}
    	for(int i=1;i<=k;i++){
    		if(!q[i][0].empty()){
    			sort(q[i][0].begin(),q[i][0].end());
    			if(q[i][0].back().first>a[i]){
    				q[i][1].push_back(make_pair(q[i][0].back().first-a[i],q[i][0].back().second));
    			}
    		}
    		if(!q[i][1].empty()){
    			sort(q[i][1].begin(),q[i][1].end(),greater<pair<int,int> >());
    			ll sum=a[i];
    			for(int j=0;j<(int)q[i][1].size();j++){
    				b.push_back(make_pair(1.0*(sum+q[i][1][j].first)/sum,q[i][1][j].second));
    				sum+=q[i][1][j].first;
    			}
    		}
    		if(!q[i][2].empty()){
    			for(int j=0;j<(int)q[i][2].size();j++){
    				b.push_back(make_pair(1.0*q[i][2][j].first,q[i][2][j].second));
    			}
    		}
    	}
    	sort(b.begin(),b.end(),greater<pair<double,int> >());
    	for(int i=0;i<m&&i<(int)b.size();i++){
    		id[++len]=b[i].second;
    	}
    	sort(id+1,id+1+len,cmp);
    	printf("%d
    ",len);
    	for(int i=1;i<=len;i++){
    		printf("%d ",id[i]);
    	}
    	puts("");
    	return 0;
    }
    
  • 相关阅读:
    二分图的判定 (图)
    并查集(模板)
    数独 (dfs)
    Map <STL>
    Set <STL>
    二叉搜索树的实现
    Find a way (BFS)
    根据输入的变量,执行相应的计算公式并返回结果
    检测字符串当中x与o的数目是否相等
    根据给定的数字和字符串,生成循环指定次数的字符串
  • 原文地址:https://www.cnblogs.com/withhope/p/13597915.html
Copyright © 2011-2022 走看看