超市(易错STL)

在这里插入图片描述
在这里插入图片描述

刚开始用map做的,TLE了,之后换priority_queue,成功AC

TLE代码:闲的没事,用stringstream花里胡哨一下

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
#include <set>
#include <map>
#include <sstream>
#define LL long long
#define mem(f, x) memset(f,x,sizeof(f)) 
#define fo(i,a,n) for(int i=a;i<n;++i)
#define foo(i,a,n) for(int i=a;i<=n;++i)
const int INF = 0x3f3f3f3f;
using namespace std;
template<class T>inline void read(T &x){
    x=0;register char c=getchar();register bool f=0;
    while(!isdigit(c))f^=c=='-',c=getchar();
    while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
    if(f)x=-x;
}
map<int,int> mp;
void op(string s){
	int a;
	stringstream ss;
	ss.clear();
	ss.str(s);
	ss>>a;//丢弃第一个数  
	while(ss>>a)//如果还有数 
		mp[a]++;
}
int main(){
	int t;
	LL sum=0;
	string s;
	getline(cin,s);
	stringstream ss;
	ss.clear();
	ss.str(s);
	ss>>t;
	while(t--){
		getline(cin,s);
		op(s);
		//迭代器遍历map 
		map<int,int>::iterator it; 
		int mx=-1e9,mn=1e9;
		for(it=mp.begin();it!=mp.end();it++){
			if((*it).first>mx)mx=(*it).first;
			if((*it).first<mn)mn=(*it).first;
		}
//		下面的方法不可以,因为map是对key排序 
//		int mx=(*mp.begin()).first,mn=(*mp.end()).first;
//		for(auto i:mp)cout<<i.first<<" "<<i.second<<endl;
		sum+=(mx-mn);
		mp[mx]--;mp[mn]--;
		if(!mp[mx])mp.erase(mx);
		if(!mp[mn])mp.erase(mn);
	}
	cout<<sum;
	return 0;
}

op函数还可以这样写(但是容易写错

void op(string s){
	int a;
	stringstream ss;
	ss.clear();
	ss.str(s);
	ss>>a;//丢弃第一个数  
	while(!ss.fail()){//如果还有数 
		ss>>a;//这个a可能是假的
		//注意坑点,下面一行代码必须加 
		if ( ss.fail() ) break;
		mp[a]++;
	}
}

易错原因:

因为读入最后一个数字后,ss仍处于正常状态,只有再尝试读入时才会出错,所以推荐第一种做法,不推荐第二种做法

AC代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
#include <set>
#include <map>
#include <sstream>
#define LL long long
#define mem(f, x) memset(f,x,sizeof(f)) 
#define fo(i,a,n) for(int i=a;i<n;++i)
#define foo(i,a,n) for(int i=a;i<=n;++i)
const int INF = 0x3f3f3f3f;
using namespace std;
template<class T>inline void read(T &x){
    x=0; char c=getchar(); bool f=0;
    while(!isdigit(c))f^=c=='-',c=getchar();
    while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
    if(f)x=-x;
}
const int N=1e6+5;
priority_queue<int> q1,q2;//默认大根堆 
int a[N];
int main(){
	int t,n;
	LL res=0;
	cin>>t;
	while(t--){
		read(n);
		fo(i,0,n){
			int x;read(x);
			q1.push(x);
			q2.push(-x);
			a[x]++;
		}
//		我得拿实际存在的数字
//		int x=q1.top(),y=-q2.top();
//		while(a[x]<=0)q1.pop();
//		while(a[y]<=0)q2.pop();
//		上面这么写就炸了,因为q1.top()和q2.top()一直在变化 
		while(a[q1.top()]<=0)q1.pop();
		while(a[-q2.top()]<=0)q2.pop();
		int x=q1.top(),y=-q2.top();
		res+=x-y;
		q1.pop();q2.pop();
		a[x]--;a[y]--;
	}
	printf("%lld",res);
	return 0;
}

想建小根堆也行:priority_queue<int,vector<int>,greater<int> > q;

类似的一道字符串读入练习题:
在这里插入图片描述
ac:

#include<bits/stdc++.h>
using namespace std;
struct f{
	string k;
	int fl;
}s[1005];
bool cmp(f a,f b){return a.fl<b.fl;}
int main(){
	string s1;
	while(getline(cin,s1)){
		stringstream s2;
		s2.clear();
		s2.str(s1);
		int a,sum=0;
		while(s2>>a)
			s[sum++].fl=a;				
		string k1;
		for(int i=0;i<sum;i++){
			cin>>k1;
			s[i].k=k1;
		}
		sort(s,s+sum,cmp);
		for(int i=0;i<sum;i++)
			cout<<s[i].k<<endl;		
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值