Codeforces Round #484 (Div. 2)

A:题目链接:点击打开链接

题目大意:给一些01串,满足俩条件:(1)两个1不能相邻;(2)这个子串在不打破上述条件的情况下,不能再放1了。

题目思路:

    第一种就是纯模拟,如果有两个相邻的1,或者出现有三个相邻的0(头尾只需两个),则输出“NO”。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;

const int inf = 0x3f3f3f3f;
const int maxn = 20005;
char s[maxn];
int n;

int main()
{
	cin>>n;
	scanf("%s",s);
	bool flag = 1;
	int tot = 0;
	for(int i=0;i<n;i++)
	{
		if(s[i]=='1'&&(s[i+1]=='1'||s[i-1]=='1'))
		{
			flag = false;
			break;
		}
		if(s[i]=='0'&&(i==0||s[i-1]=='0')&&(i==n-1||s[i+1]=='0'))
		{
			flag = false;
			break;
		}
	}
	if(!flag) {
		cout<<"No"<<endl;
	}
	else 
		cout<<"Yes"<<endl;
	return 0;
}

第二种:    

    在头尾各加上一个0,如果出现三个连续的0或者两个连续的1则输出“No”。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;

const int inf = 0x3f3f3f3f;
const int maxn = 200005;
int n;
string s;

int main()
{
	cin>>n>>s;
	s = '0'+s+'0';
	int tot = 0;
	bool flag = 1;
	for(int i=0;i<=n;i++)
	{
		if(s[i]=='1') {
			if(i>0&&s[i]==s[i-1]) {
				flag = 0;
				break;
			}
			tot = 0;
		}
		else {
			tot++;
			if(tot>=3) {
				flag = false;
				break;
			}
		}
	}
	if(!flag) {
		cout<<"No"<<endl;
	}
	else 
		cout<<"Yes"<<endl;
	return 0;
}

------------------------------------------------分割线--------------------------------------------------------------------

B题:题目链接:点击打开链接

题目大意:

    有辆公交车,共有n排,每排有2个座位,其中第i排座位的宽度均为Wi。

    现在上来2*n个旅客,他们分为两种:

    (1)只坐一排两个位置都空的位置,并且选一个(wi)最小的坐;

    (2)只坐一排另一个人的旁边(一空一有人),并且选大的坐。

     思路,首先用一个结构体从小到大排个序。然后如果上来的是第一类人,就把它这个位置加入优先队列中;如果上来的是第二类人,就把优先队列顶部的座位给他坐,并pop出去- -就完成惹。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
typedef long long ll;
using namespace std;

const int inf = 0x3f3f3f3f;
const int maxn = 200005;
int n,w[maxn],vis[maxn];
char s[maxn*2];

pair<ll,int> a[maxn*2];
vector<pair<ll,int> >e;

int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		int x;
		scanf("%d",&x);
		pair<ll,int> p;
		p.first = x;
		p.second = i+1;
		e.push_back(p);
	}
	scanf("%s",s);
	sort(e.begin(),e.end());
	priority_queue<pair<ll,int> > q;
	memset(vis,0,sizeof(vis));
	int cnt = 0;
	for(int i=0;i<n*2;i++)
	{
		if(s[i]=='0')
		{
			q.push(e[cnt]);
//			cout<<q.size()<<endl;
			cout<<e[cnt].second<<" ";
			cnt++;
		}
		else {
			cout<<q.top().second<<" ";
			q.pop();
		}
	}
	return 0;
}

------------------------------------------------分割线--------------------------------------------------------------------

C题目链接:点击打开链接

题目大意:

    给一个树(看好了是 树 ),问最多能删除几条边,使整个图所有的联通的部分都拥有偶数个节点。(我也不知道什么叫相同的尺寸,估计是所有节点和其边组成的图长的都一样)

题目思路:

    如果节点数是奇数,直接输出-1,因为这不符合常识,请问如何用3个节点组成2个一模一样的树?

    首先以节点1为根节点,统计出所有节点包含的子节点数量。如果该节点的儿子是奇数个,那么ans++;到了最后要记得ans-1,因为和根节点连着的边是不能去掉的,这辈子都不能去掉的。

    这题的话,我建议自己模拟一下。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>

using namespace std;

const int inf = 0x3f3f3f3f;
const int maxn = 200005;
vector<int> e[maxn];
int n,k,num[maxn];
bool vis[maxn];

int dfs(int x)
{
	vis[x] = 1;
	for(int i=0;i<e[x].size();i++)
	{
		if(!vis[e[x][i]])
		{
			num[x]++;
			num[x] += dfs(e[x][i]);
		}
	}	
	return num[x];
}

int main()
{
	scanf("%d",&n);
	for(int i=0;i<n-1;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		e[x].push_back(y);
		e[y].push_back(x);
	}
	if(n%2)	{
		cout<<-1<<endl;
		return 0;
	}
	num[1] = dfs(1);
	int ans = 0;
	for(auto i=1;i<=n;i++)
	{
		if(num[i]%2)
			ans++;
	}
	cout<<ans-1<<endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

总想玩世不恭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值