【codeforces #286(div 2)】ABCD题解

这次rank23~又回到紫名啦~

A.枚举插入的位置和插入的字符,暴力判断即可。

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
string S;
int s[20],n[20];
int main()
{
        cin>>S;
	for (int i=0;i<S.length();i++)
		s[i+1]=(int)(S[i]-'a'+1);
	for (int i=1;i<=S.length()+1;i++)
		for (int k=1;k<=26;k++)
		{
			n[i]=k;
			for (int j=1;j<=i-1;j++)
				n[j]=s[j];
			for (int j=i;j<=S.length();j++)
				n[j+1]=s[j];
			int l=1,r=S.length()+1;
			bool f=false;
			while (n[r]==n[l])
			{
				r--,l++;
				if (l>=r)
				{
					f=true;
					break;
				}
			}
			if (f)
			{
				for (int j=1;j<=S.length()+1;j++)
					cout<<(char)('a'+n[j]-1);
				cout<<endl;
				return 0;
			}
		}
	cout<<"NA"<<endl;
	return 0;
}

B.暴力dfs每一种颜色

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
using namespace std;
int tot=0,n,m,h[105],q,de,c[105],v[105];
struct edge
{
	int c,y,ne;
}e[10000];
void Add(int x,int y,int c)
{
	tot++;
	e[tot].y=y;
	e[tot].c=c;
	e[tot].ne=h[x];
	h[x]=tot;
}
void dfs(int x,int now)
{
	if (x==de)
	{
		c[now]=1;
		return;
	}
	for (int i=h[x];i;i=e[i].ne)
	{
		if (e[i].c!=now) continue;
		int y=e[i].y;
		if (!v[y])
		{
			v[y]=1;
			dfs(y,now);
			v[y]=0;
		}
	}
}
int main()
{
        scanf("%d%d",&n,&m);
	for (int i=1;i<=m;i++)
	{
		int x,y,co;
		scanf("%d%d%d",&x,&y,&co);
		Add(x,y,co);Add(y,x,co);
	}
	scanf("%d",&q);
	while (q--)
	{
		int x;
		scanf("%d%d",&x,&de);
		memset(v,0,sizeof(v));
		memset(c,0,sizeof(c));
		v[x]=1;
		for (int i=h[x];i;i=e[i].ne)
		{
			int y=e[i].y;
			v[y]=1;
			dfs(y,e[i].c);
			v[y]=0;
		}
		int ans=0;
		for (int i=1;i<=m;i++)
			ans+=c[i];
		cout<<ans<<endl;
	}
	return 0;
}

C.

这道题显然是个dp,但是暴力的dp超时超空间。

仔细观察可以发现最多只有500种步行的长度,比如d=1,假设每次都增加1,不到250就超过30000了;每次减少一步也同理。

这个时候dp就是500*30000了,可以过的。

注意这道题中说超过30000就不能走!!

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#define M 30005
#include <queue>
using namespace std;
struct data
{
	int p,n;
};
int c[M],n,d,f[M][505],b[M],k[M];
int main()
{
	int ma=0;
        scanf("%d%d",&n,&d);
	for (int i=1;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		c[x]++;
		ma=max(ma,x);
	}
	if (d<=250)
	{
		for (int i=1;i<=d+250;i++)
			b[i]=i,k[i]=i;
	}
	else
	{
		int now=0;
		for (int i=d-250;i<=min(30000,d+250);i++)
			b[++now]=i,k[i]=now;
	}
	memset(f,-1,sizeof(f));
	f[d][k[d]]=c[d];
	int ans=f[d][k[d]];
	for (int i=d;i<=min(ma,30000-1);i++)
		for (int j=1;j<=500;j++)
		{
			if (f[i][j]==-1) continue;
			int m=b[j];
			for (int now=max(m-1,1);now<=m+1;now++)
			{
				int de=i+now;
				if (de>30000) continue;
				f[de][k[now]]=max(f[de][k[now]],f[i][j]+c[de]),
				ans=max(ans,f[de][k[now]]);
			}
		}
	cout<<ans<<endl;
	return 0;
}

考试A了前三个。。

D题看题解明白了:

找每一个连通的块,设块中有x个点。

如果其中没有环,那么这个块要建x-1条边就可以保证全部满足,因为没有环的话,就一定可以拓扑排序,那么把拓扑排序之后的点连成一条链,就可以满足要求。

如果有环的话就要x条边了。

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
int v[200005],h2[200005],in[200005],h[200005],tot=0,k,n,m;
struct edge
{
	int y,ne;
}e[400005];
queue<int> q;
void Add(int x,int y)
{
	tot++;
	e[tot].y=y;
	e[tot].ne=h[x];
	h[x]=tot;
}
void Add2(int x,int y)
{
	tot++;
	e[tot].y=y;
	e[tot].ne=h2[x];
	h2[x]=tot;
}
void dfs(int x)
{
	if (!in[x]) q.push(x);
	tot++;
	v[x]=1;
	for (int i=h2[x];i;i=e[i].ne)
	{
		int y=e[i].y;
		if (v[y]) continue;
		dfs(y);
	}
}
int main()
{
        scanf("%d%d",&n,&m);
	for (int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		Add(x,y);
		Add2(x,y);Add2(y,x);
		in[y]++;
	}
	int ans=0;
	for (int i=1;i<=n;i++)
		if (!v[i])
		{
			tot=0;
			k=0;
			while (!q.empty())
				q.pop();
			dfs(i);
			if (tot==1) continue;
			int ok=0;
			while (!q.empty())
			{
				int x=q.front();
				q.pop();
				ok++;
				if (ok>tot) break;
				for (int i=h[x];i;i=e[i].ne)
				{
					in[e[i].y]--;
					if (!in[e[i].y]) q.push(e[i].y);
				}
			}
			if (ok==tot) ans+=(tot-1);
			else ans+=tot;
		}
	cout<<ans<<endl;
	return 0;
}

时间: 2024-11-12 22:13:00

【codeforces #286(div 2)】ABCD题解的相关文章

Codeforces Round #250 (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/433 A. Kitahara Haruki's Gift time limit per test:1 second memory limit per test:256 megabytes Kitahara Haruki has bought n apples for Touma Kazusa and Ogiso Setsuna. Now he wants to divide all the apples between th

Codeforces Round #Pi (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/567 听说Round #Pi的意思是Round #314... A. Lineland Mail time limit per test:3 seconds memory limit per test:256 megabytes All cities of Lineland are located on the Ox coordinate axis. Thus, each city is associated with it

Codeforces Round #249 (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/435 A. Queue on Bus Stop time limit per test:1 second memory limit per test:256 megabytes It's that time of the year when the Russians flood their countryside summer cottages (dachas) and the bus stop has a lot of p

Codeforces Round #313 (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/560 水笔场... A. Currency System in Geraldion time limit per test:2 seconds memory limit per test:256 megabytes A magic island Geraldion, where Gerald lives, has its own currency system. It uses banknotes of several va

Codeforces Round #302 (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/544 A. Set of Strings time limit per test:1 second memory limit per test:256 megabytes You are given a string q. A sequence of k strings s1,?s2,?...,?sk is called beautiful, if the concatenation of these strings is

Codeforces Round #533 (Div. 2) ABCD 题解

题目链接 A. Salem and Sticks 分析 暴力就行,题目给的n<=1000,ai<=100,暴力枚举t,t从2枚举到98,复杂度是1e5,完全可行. 代码 1 #include <cstdio> 2 #include <cmath> 3 #include <iostream> 4 #include <cstring> 5 #include <algorithm> 6 #include <vector> 7 #

codeforces #286 Div.2 C DP总是以意外的方式打败我

题目大意:30001个岛排成一排,编号从0到30000,一共有n个宝物分散在这些岛上,一只猪最开始从0跳到d,之后每一步跳的步长和上一步相差不超过1,第二步步长就是d-1,d,d+1,第二步的位置就是d+d-1,d+1,d+d+1如果d=1,那么下一步不能调0长,经过有宝藏的岛会把宝藏带走,问他最终能拿到多少宝藏. 因为(1+250)*250/2>30000,所以步长不会超过250——get勾 肯定要dp——get勾 如果在某个岛步长可以是1,那么这个岛之后的所有宝藏都能拿到——get勾 歧途在

Codeforces Round #286 div.1 D 506D D. Mr. Kitayuta&#39;s Colorful Graph【并查集】

题目链接:http://codeforces.com/problemset/problem/506/D 题目大意: 给出n个顶点,m条边,每条边上有一个数字,代表某个颜色.不同数字代表不同的颜色.有很多个询问,每个询问问有多少条纯种颜色的路径使得某两个点联通. 分析: 这个题一看就想用并查集来搞,每种颜色用一个并查集处理.对于输入的每条边,我们只需要将这两个点在这条边的颜色对应的并查集中合并就好了.查询的时候,我们只需要检测这两个点在多少个颜色对应的并查集中是在统一集合中的,那么就有多少条纯种颜

Codeforces Round #286 (Div. 2)B. Mr. Kitayuta&#39;s Colorful Graph(dfs,暴力)

数据规模小,所以就暴力枚举每一种颜色的边就行了. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<vector> #include<algorithm>