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

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

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

 

A. Inscribed Figures

Educational Codeforces Round 64 (Rated for Div. 2) 题解A-E_第1张图片

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

Code:

#include
#include
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>a[i];
	int ans=0;
	for(int i=1;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"<

 

B. Ugly Pairs

Educational Codeforces Round 64 (Rated for Div. 2) 题解A-E_第2张图片

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

Code:

#include
#include
#include
#include
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;il&&!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

C. Match Points

Educational Codeforces Round 64 (Rated for Div. 2) 题解A-E_第3张图片

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

Code:

#include
#include
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>a[i];
	sort(a,a+n);
	int ans=0;
	int l=0,h=n/2,r=h;
	while(l=m){
			++ans;	++l;
		}
		++r;
	}
	cout<

 

D. 0-1-Tree

Educational Codeforces Round 64 (Rated for Div. 2) 题解A-E_第4张图片

思路:树状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
#include
#include
using namespace std;
typedef long long LL;
typedef pair pr;

const int MAX_N=2e5+5;
int n;
LL ans;
LL d0[MAX_N],d1[MAX_N],d2[MAX_N];
vector 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>u>>v>>w;
		e[u].push_back({v,w});
		e[v].push_back({u,w});
	}
	DFS(1,0);
	DFS1(1,0);
	cout<

 

E. Special Segments of Permutation

Educational Codeforces Round 64 (Rated for Div. 2) 题解A-E_第5张图片

思路:二分+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
#include
#include
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 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::iterator f;
	for(int i=n;i>=3;--i)
		if(d[i]>1&&d[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]]

 

你可能感兴趣的:(Codeforces,二分,树状DP,贪心)