2019.10.2Codeforces Round #590 (Div. 3)补题

这几天CF好像被墙了呀,昨天晚上用m3的分站打的。

题解在这

A.Equalize Prices Again

题意

将n个商品设置为统一价格,但总价值不低于当前,求出该价格

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<climits>
#include<cmath>
#include<iomanip>//控制输出,<<setiosflags(ios::fixed)<<setprecision(9)
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<map>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
//#define DEBUG
int a[1005];
int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	#ifdef DEBUG
		freopen("input.txt", "r", stdin);
	//	freopen("output.txt", "w", stdout);
	#endif
	int q;
	cin>>q;
	while(q--)
	{
		int n;
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			cin>>a[i];
			a[i]+=a[i-1];
		}
//		int ans=a[n]/n;
//		cout<<"ans=";
		if(a[n]%n==0)
			cout<<a[n]/n<<endl;
		else
			cout<<a[n]/n+1<<endl;
	}
	return 0;
}

B1&&B2.Social Network

题意

你的一群基友不停给你发消息,n条消息,屏幕最多可以显示k条。
新收到一条消息,若发信人已经在屏幕上,则无变化。
否则若显示数目小于k,该发信人显示在屏幕顶端。
若显示数目等于k,该发信人显示在屏幕顶端,并去掉原本在屏幕底端的发件人。

思路

同时在两端操作,用list模拟即可

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<climits>
#include<cmath>
#include<iomanip>//控制输出,<<setiosflags(ios::fixed)<<setprecision(9)
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<list>
#include<map>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
//#define DEBUG
int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	#ifdef DEBUG
		freopen("input.txt", "r", stdin);
	//	freopen("output.txt", "w", stdout);
	#endif
	int n,k,cnt=0,id,que[205];
	map<int,bool> TAT;
	list<int> QAQ;
	cin>>n>>k;
	for(int i=1;i<=n;i++)
	{
		cin>>id;
		if(TAT[id])
			continue;
		else if(QAQ.size()<k){
			TAT[id]=1;
			QAQ.push_front(id);
		}
		else{
			TAT[QAQ.back()]=0;
			QAQ.pop_back();
			TAT[id]=1;
			QAQ.push_front(id);
		}
	}
	cout<<QAQ.size()<<endl;
	while(!QAQ.empty())
	{
		cout<<QAQ.front()<<' ';
		QAQ.pop_front();
	}
	return 0;
}

C.Pipes

题意

水管零件有两种,给你2*n的管道,问你水流是否能从(1,1)流到(2,n)

思路

大模拟即可

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<climits>
#include<cmath>
#include<iomanip>//控制输出,<<setiosflags(ios::fixed)<<setprecision(9)
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<map>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
int a[2][200005];
int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	#ifdef DEBUG
		freopen("input.txt", "r", stdin);
	//	freopen("output.txt", "w", stdout);
	#endif
	int q,n;
	cin>>q;
	while(q--)
	{
		cin>>n;//从(1,1)到(2,n)
		char ch;
		for(int i=0;i<=1;i++)
			for(int j=1;j<=n;j++)
			{
				cin>>ch;
				a[i][j]=(ch=='1'||ch=='2')?1:2;
			}
		int fir=0;
		bool flag=0;
		for(int i=1;i<=n;i++)
		{
			if(a[fir][i]==2)//上下移动
			{
				if(fir==0)
				{
					fir=1;
				}
				else{
					fir=0;
				}
				if(a[fir][i]==1)//下一个是直管
					break;
			}
			if(fir==1&&i==n)
				flag=1;
		}
		cout<<(flag?"YES":"NO")<<endl;
	}
	return 0;
}

D.Distinct Characters Queries

呜呜呜,这题本来想用前缀和差分做的。
没做出来,问了下学长才用set+二分补了题。

题意

给你一段只有小写字母的字符串,和q个操作。
操作分为两种,第一种操作将pos位置的字符替换为ch。
第二种操作为查询a与b区间的字母种类数。

思路

使用set存储每个字母的位置,同时用set自带的二分查找查找离a最近的位置,并于b比较。
为了防止set返回查找失败的地址,一开始在每个set里存一个大于str长度的数。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<climits>
#include<cmath>
#include<iomanip>//控制输出,<<setiosflags(ios::fixed)<<setprecision(9)
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<unordered_map>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
//#define DEBUG
char str[100005];
int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	#ifdef DEBUG
		freopen("D.txt", "r", stdin);
	//	freopen("output.txt", "w", stdout);
	#endif
	int q;
	scanf("%s%d",str+1,&q);
	int len=strlen(str+1);
	unordered_map<char,int> mp;
	set<int> st[27];
	for(int i=1;i<=26;i++)
	{
		mp['a'+i-1]=i;//按顺序映射
		st[i].insert(100010);
	}
	char ch;
	for(int i=1;i<=len;i++)
	{
		ch=str[i];
		st[mp[ch]].insert(i);
	}
	while(q--)
	{
		int req;
		scanf("%d",&req);
		if(req==1)//修改
		{
			int pos;
			scanf("%d %c",&pos,&ch);
			st[mp[str[pos]]].erase(pos);
			st[mp[ch]].insert(pos);
			str[pos]=ch;
		}
		else{
			int a,b;
			scanf("%d%d",&a,&b);
			int cnt=0;
			for(int i=1;i<=26;i++)
			{//判断长度
				if(*st[i].lower_bound(a)<=b)
				{
					cnt++;
				}
			}
			printf("%d\n",cnt);
		}
	}
	return 0;
}

E. Special Permutations

题面长的一批,数学公式在m3分站各种崩坏,根本看不了啊

题意

给你n与m,表示有n组排列, p i ( n ) pi(n) [ 1 , 2 , . . . , n 1 , n ] [1,2,...,n-1,n] 的自然数列将 i i 提前到首位。
再给你有m个元素的x数组, 1 < = x i < = n 1<=xi<=n
输出n个数:
x数组中相邻的两个元素在 p i ( n ) pi(n) 的距离之和

思路

题面好乱啊……[尬笑]
还是我太菜了……

发布了71 篇原创文章 · 获赞 12 · 访问量 7545

猜你喜欢

转载自blog.csdn.net/Miaplacidus/article/details/101915021