ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

NOIP提高组模拟赛夜间版2

2022-04-04 12:01:46  阅读:139  来源: 互联网

标签:夜间 return NOIP int ll dfs include 模拟 式子


没想到这个系列还能再更新

A. 装饰

这种题就需要大胆猜测打表验证

反正就是推出来了,式子变化一下就是题解式子,就是有亿点不简洁

我是这么想的(大概)

先排序,两个较小的颜色可以看成一个,这样只用考虑两种颜色,取法只有\(1-2\)

令两种颜色数量为\(a,b(a<b)\)

  1. \(a*2<=b\)显然按照\(a\)取\(1\),b取\(2\)后\(b\)有剩余,答案是\(a\)

  2. \(a*2>b\),那么每次操作可以令两种颜色数量差\(-1\),可以推一下,然后写出一个简单式子,实际上这样的结果是剩下的数量一定为\(0-0,1-0,0-1,1-1,0-2,2-0\),实际上就是\((a+b+c)%3\),那么答案其实就是\((a+b+c)/3\),当然也可以写一堆恶心式子

code
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

typedef long long ll;

ll a[4];

ll work(){
	ll ans=0;
	a[2]+=a[1];
	if(a[3]<a[2]){a[2]^=a[3];a[3]^=a[2];a[2]^=a[3];}
	if(a[2]+a[2]<=a[3])return ans+a[2];
	ans+=a[3]-a[2];
	a[2]=a[3]=a[2]+a[2]-a[3];
	ans+=(a[2]/3)*2;
	a[2]%=3;a[3]%=3;
	if(a[2]==2)++ans;
	return ans;
}

int main(){
	freopen("decorate.in","r",stdin);
	freopen("decorate.out","w",stdout);
	int T;scanf("%d",&T);
	for(int ask=1;ask<=T;++ask){
		for(int i=1;i<=3;++i)scanf("%lld",&a[i]);
		sort(a+1,a+3+1);
		printf("%lld\n",work());
	}
	return 0;
}

B. 凉宫春日的消失

感谢数据,让我水了\(65pts\)

发现一定有解,跟\(dfs\)序有关,然后就莽了个按照\(dfs\)序排序

实际上离正解只有一步之遥

我们先让点集里的点按\(dfs\)序排序,然后相邻的两点都进行配对,第一个再和最后一个配对,这样我们把每个点配了两对

想一想深搜的路径,发现此时最多每条边经过两次

也就是说\(\sum_{i=1}^{cnt}path<=2(n-1)\)

我们只需要两两配对,那么只需要保留一半的路径,\(1,3,5....\)或者\(2,4,6....\)

他们有一个一定\(<=n-1\)

简单判断一下一种方案是否可行即可

code
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn=200005;

struct edge{int net,to;}e[maxn<<1|1];
int head[maxn],tot;
void add(int u,int v){
   e[++tot].net=head[u];
   head[u]=tot;
   e[tot].to=v;
}

int f[maxn][21],dfn[maxn],tim,dep[maxn],ls[maxn];

bool cmp(int x,int y){
	return dfn[x]<dfn[y];
}

void dfs(int x){
	dfn[x]=++tim;
	for(int i=head[x];i;i=e[i].net){
		int v=e[i].to;
		if(v==f[x][0])continue;
		f[v][0]=x;dep[v]=dep[x]+1;
		dfs(v);
	}
}

int LCA(int x,int y){
	if(dep[y]>dep[x]){x^=y;y^=x;x^=y;}
	for(int i=20;i>=0;--i)if(dep[x]-dep[y]>=(1<<i))x=f[x][i];
	if(x==y)return x;
	for(int i=20;i>=0;--i)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
	return f[x][0];
}

bool check(int s,int n){
	if(s&1)return false;
	int sum=0;
	for(int i=1;i<=s;i+=2){
		int lca=LCA(ls[i],ls[i+1]);
		sum+=dep[ls[i]]-dep[lca]+dep[ls[i+1]]-dep[lca];
		if(sum>n)return false;
	}
	return true;
}
int main(){
	freopen("kieru.in","r",stdin);
	freopen("kieru.out","w",stdout);
	int n;scanf("%d",&n);
	for(int i=1;i<n;++i){
		int u,v;scanf("%d%d",&u,&v);
		add(u,v);add(v,u);
	}
	dep[1]=1;dfs(1);
	for(int j=1;j<=20;++j)
	 for(int i=1;i<=n;++i)
	   f[i][j]=f[f[i][j-1]][j-1];
	int s;scanf("%d",&s);
	while(s){
		for(int i=1;i<=s;++i)scanf("%d",&ls[i]);
		sort(ls,ls+s+1,cmp);
		printf("Yes\n");
		if(check(s,n)){	
			for(int i=1;i<=s;i+=2)printf("%d %d\n",ls[i],ls[i+1]);
		}else {
			printf("%d %d\n",ls[1],ls[s]);
			for(int i=2;i<s;i+=2)printf("%d %d\n",ls[i],ls[i+1]);
		}
		scanf("%d",&s);
	}
	return 0;
}

标签:夜间,return,NOIP,int,ll,dfs,include,模拟,式子
来源: https://www.cnblogs.com/Chencgy/p/16098733.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有