Educational Codeforces Round 64 (Rated for Div. 2) 题解A-E

42 篇文章 0 订阅
33 篇文章 0 订阅

地址: http://codeforces.com/contest/1156

做了前3题,好不容易可以上分,结果不评分,有点难受。。

 

A. Inscribed Figures

思路:题目有点长。。,然后看了一半就直接看样例了(还是样例容易看懂),wa了一次,注意 3-1-2的情况有一个点是重合了

Code:

#include<iostream>
#include<algorithm>
using namespace std;

const int MAX_N=2e5+5;
int n,m,T;
int a[MAX_N];
int d[5][5];

int main()
{
	ios::sync_with_stdio(false);
	d[1][2]=3;	d[1][3]=4;
	d[2][1]=3;	d[2][3]=-1;
	d[3][1]=4;	d[3][2]=-1;
	cin>>n;
	for(int i=0;i<n;++i)
		cin>>a[i];
	int ans=0;
	for(int i=1;i<n;++i)
	{
		if(d[a[i-1]][a[i]]==-1){
			ans=-1;	break;
		}
		if(i>=2&&a[i-2]==3&&a[i-1]==1&&a[i]==2)	--ans;
		ans+=d[a[i-1]][a[i]];
	}
	if(ans!=-1){
		cout<<"Finite"<<endl;
		cout<<ans<<endl;
	}else	cout<<"Infinite"<<endl;
	
	return 0;
}

 

B. Ugly Pairs

思路:构造题。开始题目看错了,以为相同的字符相邻是不可以的,写了半天没写出来,然后一看题目列表已经过了600多了,就觉得奇怪,应该没这么难,然后看样例就发现相同字符相邻是可以的QAQ. 这样的话就只要对不同的字符进行构造即可,然后改了下先前写的代码就ok了。。大体思路是从两端交替摆放。最后判断有多少个非法摆放,若小于1个则从非法处拆开再首位合并起来即可。

Code:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;

int n,T;
int d[30];
char res[105];
string str;

int main()
{
	ios::sync_with_stdio(false);
	cin>>T;
	while(T--){
		memset(d,0,sizeof(d));
		cin>>str;
		n=str.length();
		for(int i=0;i<n;++i)
			++d[str[i]-'a'];
		int l=0,r=25,s=0;
		while(l<r){
			while(l<r&&!d[l]){
				++l;
			}
			while(r>l&&!d[r]){
				--r;
			}
			if(l==r)	break;
			if(d[l]){
				res[s++]=char(l+'a');
				++l;
			}
			if(d[r]){
				res[s++]=char(r+'a');
				--r;
			}
		}
		if(l==r&&d[l]){
			res[s++]=char(l+'a');
		}
		int boo=0;
		l=0;
		if(abs(res[0]-res[s-1])==1)	++boo;
		for(int i=1;i<s;++i)
			if(abs(res[i]-res[i-1])==1){
				++boo;	l=i;
			}
		if(boo<=1){
			for(int i=l;i<s;++i)
				for(int j=0;j<d[res[i]-'a'];++j)
					cout<<res[i];
			for(int i=0;i<l;++i)
				for(int j=0;j<d[res[i]-'a'];++j)
					cout<<res[i];
			cout<<endl;
		}else	cout<<"No answer"<<endl;
	}

	return 0;
}

C. Match Points

思路:贪心。比赛时是做了A(后来重测wa了。。)之后看题目发现C过的也挺多的,然后看下C就发现这题我做过啊,然后刷刷刷的就一遍过了^v^. 这题用贪心思路,先由小到大排序,在看要找的[l,r]都是一对对的,因此最多找到n/2个,因此将数组对半分,l从左半边开始,r从右半边开始找,每次用r去匹配l即可

Code:

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;

const int MAX_N=2e5+5;
int n,m,T;
int a[MAX_N];

int main()
{
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=0;i<n;++i)
		cin>>a[i];
	sort(a,a+n);
	int ans=0;
	int l=0,h=n/2,r=h;
	while(l<h&&r<n){
		if(a[r]-a[l]>=m){
			++ans;	++l;
		}
		++r;
	}
	cout<<ans<<endl;

	return 0;
}

 

D. 0-1-Tree

思路:树状DP。对每个节点作为路线的起点分析。假定1节点为整个树的根节点。首先DFS一遍找到以每个节点为根节点的树的d0[i],d1[i],d2[i]的数量。其中

d0[i]:以i节点为根节点的树中,从根节点出发路径权值都是0的路径数。

d1[i]:以i节点为根节点的树中,从根节点出发路径权值都是1的路径数。

d2[i]:以i节点为根节点的树中,从根节点出发路径权值开始是1后来是0的路径数。

在DFS一遍求出以每个节点为起点的合法路径数Si。而显然Si=d0[i]+d1[i]+d2[i]。但是这里的d0[i],d1[i],d2[i]应该是以i节点为整个树的根节点,而第一次DFS求的是以1节点为整个树的根节点下的 i节点的树。因此求Si时,需要将i节点的父亲节点的d0,d1,d2转移到 i节点上来,而这个转移则可通过 i节点和其父亲节点的连接线的权值w来分类讨论即可

Code:

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long LL;
typedef pair<int,int> pr;

const int MAX_N=2e5+5;
int n;
LL ans;
LL d0[MAX_N],d1[MAX_N],d2[MAX_N];
vector<pr> e[MAX_N];
/*
对每个点作为起点分析QAQ
*/
void DFS(int u,int pre);
void DFS1(int u,int pre);
int main()
{
	ios::sync_with_stdio(false);
	cin>>n;
	int u,v,w;
	for(int i=1;i<n;++i)
	{
		cin>>u>>v>>w;
		e[u].push_back({v,w});
		e[v].push_back({u,w});
	}
	DFS(1,0);
	DFS1(1,0);
	cout<<ans<<endl;

	return 0;
}

void DFS(int u,int pre)
{
	int v,w;
	for(auto c:e[u])
		if(c.first!=pre){
			v=c.first;	w=c.second;
			DFS(v,u);
			if(!w){
				d0[u]+=d0[v]+1;
			}else{
				d1[u]+=d1[v]+1;
				d2[u]+=d2[v]+d0[v];
			}
		}
}

void DFS1(int u,int pre)
{
	int v,w;
	for(auto c:e[u])
		if(c.first!=pre){
			v=c.first;	w=c.second;
			if(!w){
				d0[v]=d0[u];
			}else{
				d1[v]=d1[u];
				d2[v]=d2[u]+d0[u]-d0[v];
			}
			DFS1(v,u);
		}
	ans+=d0[u]+d1[u]+d2[u];
}

 

E. Special Segments of Permutation

思路:二分+set

题目要求区间[l,r]中 a[l]+a[r]=max(a[l-->r]),对max{a[i]}继续分析,可以看出关键点max{a[i]},即最大值是影响到比它小的值的求解的。那么对a[l]+a[r]=a[i]的a[i]由大到小进行遍历,对于a[i]的区间边界l,r求解,肯定是包含a[i]且比a[i]大的点组成的边界,用d[i]记录值为i的点的下标值。这个可以用set自带的排序+二分查找来找到l,r.再求a[i]的解时,可以遍历[l,r]中离a[i]点近的一边x,再判断a[i]-x是否在另一边即可。在处理完a[i],在将a[i]点所处的位置下标加入set即可

Code:

#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
typedef long long LL;

const int MAX_N=2e5+5;
int n;
LL ans;
int a[MAX_N],d[MAX_N];
set<int> iset;

void Find(int p,int l,int r);
int main()
{
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=1,x;i<=n;++i)
	{
		cin>>a[i];
		d[a[i]]=i;
	}
	iset.insert(0);
	iset.insert(n+1);
	int l,r;
	set<int>::iterator f;
	for(int i=n;i>=3;--i)
		if(d[i]>1&&d[i]<n){
			f=iset.lower_bound(d[i]);
			r=*f;	l=*(--f);
			Find(i,l+1,r-1);
			iset.insert(d[i]);
		}
	cout<<ans<<endl;

	return 0;
}

void Find(int p,int l,int r)
{
	int h=d[p];
	if(h-l<r-h){
		for(int i=l;i<h;++i)
			if(p-a[i]>0&&d[p-a[i]]>h&&d[p-a[i]]<=r)	++ans;
	}else{
		for(int i=h+1;i<=r;++i)
			if(p-a[i]>0&&d[p-a[i]]>=l&&d[p-a[i]]<h)	++ans;
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"educational codeforces round 103 (rated for div. 2)"是一个Codeforces平台上的教育性比赛,专为2级选手设计评级。以下是有关该比赛的回答。 "educational codeforces round 103 (rated for div. 2)"是一场Codeforces平台上的教育性比赛。Codeforces是一个为程序员提供竞赛和评级的在线平台。这场比赛是专为2级选手设计的,这意味着它适合那些在算法和数据结构方面已经积累了一定经验的选手参与。 与其他Codeforces比赛一样,这场比赛将由多个问题组成,选手需要根据给定的问题描述和测试用例,编写程序来解决这些问题。比赛的时限通常有两到三个小时,选手需要在规定的时间内提交他们的解答。他们的程序将在Codeforces的在线评测系统上运行,并根据程序的正确性和效率进行评分。 该比赛被称为"educational",意味着比赛的目的是教育性的,而不是针对专业的竞争性。这种教育性比赛为选手提供了一个学习和提高他们编程技能的机会。即使选手没有在比赛中获得很高的排名,他们也可以从其他选手的解决方案中学习,并通过参与讨论获得更多的知识。 参加"educational codeforces round 103 (rated for div. 2)"对于2级选手来说是很有意义的。他们可以通过解决难度适中的问题来测试和巩固他们的算法和编程技巧。另外,这种比赛对于提高解决问题能力,锻炼思维和提高团队合作能力也是非常有帮助的。 总的来说,"educational codeforces round 103 (rated for div. 2)"是一场为2级选手设计的教育性比赛,旨在提高他们的编程技能和算法能力。参与这样的比赛可以为选手提供学习和进步的机会,同时也促进了编程社区的交流与合作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值