首页 > 其他分享 >Codeforces Round 869 (Div. 2) A-D题解

Codeforces Round 869 (Div. 2) A-D题解

时间:2023-05-03 12:55:48浏览次数:42  
标签:869 环上 int 题解 void back st vis Div

比赛地址

A. Politics

题意:有n个人对m个决案进行投票,对于每一个决案如果票数相同则所有人都离场,反之票数少的一方离场,现在提前知道了每个人的意见,让一些人参与投票,在保证第一个人不离场的情况下最终剩余人数最多是多少

Solution

把和第一个意见不同的给去掉就行了

void solve()
{
	int n,k;cin>>n>>k;
	set<int>st;
	for(int i=1;i<=n;i++)
	{
		cin>>s[i];
		st.insert(i);
	}
	int ans=n;
	int cnt=0;
	for(int i=0;i<k;i++)
	{
		for(auto it:st)
		{
			if(s[it][i]!=s[1][i])
			{
				a[++cnt]=it;
			}
		}
		while(cnt>0)st.erase(a[cnt--]);
		
	}
	cout<<st.size()<<"\n";
}

B. Indivisible

题意:构造一个由[1,2,...,n]组成的数组,使得任意一个区间长度大于等于2的区间,其区间和不能被区间长度整除

Solution

打表找找规律,发现直接2,1,4,3,6,5,....,n,n-1构造就行了,奇数是肯定不行的,因为n为奇数时,n+1为偶数,n*(n+1)/2可以被n整除

void dfs(int x)  //打表
{
	if(x>n)
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=i+1;j<=n;j++)
			{
				int sum=0;
				for(int k=i;k<=j;k++)
				{
					sum+=a[k];
				}
				if(sum%(j-i+1)==0)return;
			}
		}
		for(int i=1;i<=n;i++)cout<<a[i]<<" ";
		cout<<"\n";
		return;
	}
	for(int i=1;i<=n;i++)
	{
		if(vis[i])continue;
		vis[i]=1;
		a[x]=i;
		dfs(x+1);
		vis[i]=0;
	}
}

void solve()
{
	cin>>n;
	if(n==1)
	{
		cout<<"1\n";
		return;
	}else if(n&1)
	{
		cout<<"-1\n";
		return;
	}
	for(int i=1;i<=n;i+=2)cout<<i+1<<" "<<i<<" ";
	cout<<"\n";
}

C. Almost Increasing Subsequence

题意:定义几乎增加子序列不存在连续的x,y,z,满足x>=y>=z,给出一个长为n的数组,对其进行q次询问,每次询问输出最长的几乎增加子序列的长度

Solution

前缀和,先处理以a[i]为结尾的三个连续的数是否满足a[i-2]>=a[i-1]>=a[i]

然后用前缀和记录一遍数量,对于每一个询问区间,答案是r-l+1-(s[r]-s[l+1])

说实话我不会证明这个结论的充分必要性,感觉是对的就这么写了(

void solve()
{
	int n,m;cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i];
	
	for(int i=3;i<=n;i++)
	{
		if(a[i-2]>=a[i-1]&&a[i-1]>=a[i])vis[i]=1;
		s[i]=s[i-1]+vis[i];
	}
	
	while(m--)
	{
		int l,r;cin>>l>>r;
		if(r-l+1<3)cout<<r-l+1<<'\n';
		else cout<<r-l+1-(s[r]-s[l+1])<<"\n";
	}
	
}

D. Fish Graph

题意:给出一个无向图,问是否存在一个环,环满足环上存在一特殊点,去掉环上的边后,这个特殊点还有至少两条边

Solution

想法就是枚举每个特殊点,看它是否在环上,并且除了环上的边还有两条边

那么这样的点的度一定是>=4的,再就是找环,dfs递归找,一开始是用vector存边,但是后来发现好麻烦,就直接存点

当找到环的时候,我们就通过每个点的父节点把所有的点都存下来,然后再把所有的点都标记为环上的点,再遍历特殊点的其他边

因为答案只需要两个,所以我们也只用遍历两条其他边

然后就...WA了

问题来了,一个特殊点可能在多个环上,不过题目没有对环作出要求,所以我们还需要把环缩小,从特殊点的下一个点的下一个点开始遍历,看是否存在一个点和特殊点之间有边,这样就可以达到缩小环的目的

vector<int>e[N];
int vis[N]; 
int check[N];  
vector<int>c;  //存环上的点
int flag=0;
int fa[N];
void dfs(int x,int pre,int st)
{
	vis[x]=1;
	if(flag)return;
	for(auto it:e[x])
	{
		if(it==pre)continue;
		if(flag)return;
		if(it==st)
		{
			int t=x;
			while(x!=st)
			{
				c.push_back(x);
				check[x]=1;
				x=fa[x];
			}
			c.push_back(it);
			check[it]=1;
			flag=1;
			return;
		}
		
		if(!vis[it])
		{
			fa[it]=x;
			dfs(it,x,st);
		}
		
	}
}


void solve()
{
	int n,m;cin>>n>>m;
	for(int i=1;i<=n;i++)e[i].clear();
	for(int i=1;i<=m;i++)
	{
		int u,v;cin>>u>>v;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	for(int i=1;i<=n;i++)
	{
		if(e[i].size()<4)continue;
		for(int i=1;i<=n;i++)vis[i]=check[i]=fa[i]=0;
		c.clear();
		flag=0;
		
		dfs(i,0,i);
		
		if(!flag)continue;
		for(auto it:e[i])vis[it]=-1;
		int sz=2;
		for(int i=c.size()-3;i>=0;i--)
		{
			sz++;
			if(vis[c[i]]==-1)
			{
				break;
			}
		}
		while(c.size()>sz)
		{
			auto it=*c.begin();
			check[it]=0;
			c.erase(c.begin());
		}
		
		vector<int>tt;
		for(auto it:e[i])
		{
			if(!check[it])tt.push_back(it);
			if(tt.size()==2)break;
		}

		cout<<"YES\n";
		cout<<c.size()+2<<"\n";
		cout<<tt[0]<<" "<<i<<"\n";
		cout<<tt[1]<<" "<<i<<"\n";
		int len=c.size();
		for(int i=0;i<len;i++)
		{
			cout<<c[i]<<" "<<c[(i+1)%len]<<"\n";
		}
		return;
	}
	cout<<"NO\n";
}

标签:869,环上,int,题解,void,back,st,vis,Div
From: https://www.cnblogs.com/HikariFears/p/17368933.html

相关文章

  • CF1416 Div.1 VP记
    好久没打CF了,感觉写代码能力有所下降,vp一场看看,差点被阻击没了。ACF题面先考虑将某一个数字提出来,可以发现如果这个数字要对答案造成贡献,那么\(k\)最小为没有该数字的区间中最长的区间长度加一。点击查看代码#include<bits/stdc++.h>#defineullunsignedlonglong#def......
  • Chemistry Experiment Codeforces Round 247 (Div. 2) 线段树动态开点,二分
    第一次写的时候还不会线段树的动态开点,写了一个是线段树但是是\(O(N^2)\)的写法,现在用动态开点武装了自己,会了正解\(O(qlogn^2)\)。首先建立一个权值线段树,但这里的权值很大,通过动态开点去建树来节省空间,对于两种操作:操作1,常见的动态开点的单点修改操作2,二分答案,然后在线段树......
  • AT_abc106_d [ABC106D] AtCoder Express 2 题解
    题目传送门解题思路区间\(dp\)。划分阶段:以左右城市之间的列车数量为阶段。状态表达:设\(f_{i,j}\)为城市\(i\)与城市\(j\)之间的列车数量。状态转移:由图可知,城市\(l\)与城市\(r\)之间的列车数量,就是城市\(l\)与城市\(r-1\)之间的列车数量与城市\(l+1\)与......
  • CF1817C Similar Polynomials 题解
    可能更好的阅读体验题目传送门Div.1C拉格朗日差值,赛时开香槟。题目大意给定\(d\)次两个多项式\(A(x),B(x)\)。求\(s\),使得\(B(x)\equivA(x+s)\pmod{10^9+7}\),保证\(s\)存在。给出多项式的形式为给出\(x=0,1,\cdots,d\)模\(10^9+7\)的值。\(d\le2.5\times......
  • CF三月D题题解
    cf1798d题意:重排序列,使得其中连续子序列和的绝对值最大的最大值小于序列最大值减最小值,序列和为0考虑这样一种构造方案:正负数分类,0直接不管然后记录当前和sum,当sum非负时,加上一个负数,当sum是负数时,加上一个正数即可正确性证明:显然前缀和都是合法的。考虑计算前缀和数组,满足......
  • 「BZOJ2144」跳跳棋-题解
    「BZOJ2144」跳跳棋个人评价挺好的一道题,难点在于想到树这个结构和建树1题面跳跳棋是在一条数轴上进行的。棋子只能摆在整点上。每个点不能摆超过一个棋子。我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置。我们要通过最少的跳动把他们的位置移......
  • Educational Codeforces Round 147 (Rated for Div. 2) 题解
    ALink。模拟,代码。BLink。模拟,代码。CLink。我们设\(c\)为最后相同的字符。性质:我们一定不会删除字符\(c\)。因此以\(c\)为最后字符的操作次数就是不包含字符\(c\)的极大段的最小操作次数的最大值。对于一个长度为\(l(l\ge1)\)的段,它的最小操作次数为\(\l......
  • P4198 楼房重建 题解
    P4198楼房重建题解线段树二分思路考虑在线段树内维护二信息:区间斜率最大值\(mx\)区间最大斜率上升序列长度\(len\)答案即为根节点的\(len\)。考虑转移信息二:蓝色部分代表左区间的上升序列,红色是右区间的,绿色折线就是当前区间的上升序列。......
  • P2051 [AHOI2009] 中国象棋 题解
    DP。状态设计是点睛之笔。首先显然有每行或每列只能有至多\(2\)个棋子。设状态\(f_{i,j,k}\)为第\(i\)行,有\(j\)列只放了一个棋子,\(k\)列放了两个棋子。之后直接转移即可。注意边界判断。code:点击查看代码#include<bits/stdc++.h>#definelllonglong#defined......
  • Java cmd下编译乱码问题解决办法
    1、报错样式 2、解决办法1)指定字符集,如下 2)修改编码格式通过“记事本”打开—》另存为3)修改环境变量此电脑——》属性——》高级系统设置——》环境变量——》(系统环境变量)新建——》“JAVA_TOOL_OPTIONS” “-Dfile.encoding=UTF-8”如下图:——》重启cmd,再......