Codeforces Round #590 (Div. 3)

题目链接

A: Equalize Prices Again
B2: Social Network (hard version)
C: Pipes
D: Distinct Characters Queries

A:
题意:求n个数和的平均值,向上取整。

#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int a[10005];
 
int main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		int sum=0;
		cin>>n;
		for(int i=1;i<=n;i++){
			cin>>a[i];
			sum+=a[i];
		}			
		int ans=sum/n;
		if(ans*n<sum){
			ans++;
		}
		cout<<ans<<endl;
	}
	return 0;
}

B:
题意:对n(2e5)个数进行模拟操作:有一个最大大小为k(2e5)的队列,如果第i个数没有在队列中出现过,而且队列size小于k,直接放入,否则弹出队列头,放入第i个数。(比较难读懂,看样例说明可以看懂)
思路:直接用STL模拟即可,用map查找数字在不在队列中复杂度为logk,因此复杂度是O(nlogk)

#include<iostream>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#define ll long long
using namespace std;
int a[200005];
map<int,bool> mp;
queue<int> q;
vector<int> v;
int main(){
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	for(int i=1;i<=n;i++){
		if(mp[a[i]])
			continue;
		if(q.size()<k){
			q.push(a[i]);
			mp[a[i]]=1;
			continue;
		}
		if(q.size()==k){
			mp[q.front()]=0;
			q.pop();
			q.push(a[i]);
			mp[a[i]]=1;
		}
	}
	cout<<q.size()<<endl;
	while(!q.empty()){
		v.push_back(q.front());
		q.pop();
	}
	for(int i=v.size()-1;i>=0;i--)
		cout<<v[i]<<" ";
	return 0;
}

C:
题意:
转水管的游戏,问目前水管状态有没有解
思路:
1.2种水管实际只能平着运,3.4.5.6水管可以向上或向下并平着运一格,O(n)一遍模拟水走,看最后会运到哪里,是否是目标位置

#include<iostream>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#define ll long long
using namespace std;
char s[2][200005];
int main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		scanf("%s",s[0]);
		scanf("%s",s[1]);
		int j=0;
		int i=0;
		for(i=0;i<n;i++){
			if(s[j][i]>='3'){
				if(s[j^1][i]<='2'){
 
					break;
				}
				else
					j^=1;			
			}
		}
		if(i==n&&j==1)
			cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
}

D:
题意:给一个字符串,两个操作,1是替换字符串中一个位置的字母,2是查询l到r区间中出现了多少个不同的字母
思路:乍一看线段树,然后就没写。后来看题解是写了26个set,每个set维护,第i个字母出现的每个位置,对于每次查询,for一遍每个字母,二分查找看是否在区间中,复杂度O(26nlogn)

#include<iostream>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cstring>
#include<set>
#define ll long long
using namespace std;
char init[200005];
vector<set<int> > v;
set<int> s; 
int main(){
	scanf("%s",init);
	int l=strlen(init);
	for(int i=0;i<26;i++)
		v.push_back(s);
	for(int i=0;i<l;i++){
		v[init[i]-'a'].insert(i);
	}
	int q;
	scanf("%d",&q);
	while(q--){
		int op;
		scanf("%d",&op);
		if(op==1){
			int p;char a;
			scanf("%d %c",&p,&a);
			p--;
			v[init[p]-'a'].erase(p);
			init[p]=a;
			v[a-'a'].insert(p);
		} 
		else{
			int l,r;
			scanf("%d%d",&l,&r);
			int ans=0;
			l--,r--;
			for(int i=0;i<26;i++){
				auto it=v[i].lower_bound(l);
				if(it==v[i].end())
					continue;
				
				if(*it<=r){
					ans++;
			//		cout<<char(i+'a')<<" "<<*it<<endl;
				}
					
			}
			printf("%d\n",ans);	
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值