牛客挑战赛35 总结

。。。

持续菜炸


本着一血拿卫衣的想法,我开始了这场挑战赛

众所周知T1一般是水题,于是我早已做好了准备
准备1
nmsl
看到T1,给定两个数组,自行决定顺序,使 ∑ m a x { b i − a i , 0 } \sum max\{b_i-a_i,0\} max{biai,0}最大

一眼贪心,排序计算即可,时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)

#include<cctype>
#include<cstdio>
#include<algorithm>
#define LL long long
using namespace std;int n,a[100010],b[100010]; 
LL ans;
inline LL read()
{
	char c;LL d=1,f=0;
	while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
	while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
	return d*f;
}
signed main()
{
	n=read();
	for(register int i=1;i<=n;i++) a[i]=read();
	for(register int i=1;i<=n;i++) b[i]=read();
	sort(a+1,a+1+n);sort(b+1,b+1+n);
	for(register int i=1;i<=n;i++) ans+=max(0,b[n-i+1]-a[i]);
	printf("%lld",ans);
}

于是我的码题手速得到极致发挥,可惜。。。

终究慢了30秒。。。

失去了卫衣的我心灰意冷,加之AJ鸡汤罚时,早已失去信心

T2是给定一张无向图,求边变点,点边变重复无穷次后点的数量
肛了好久的规律,这里直接放出来

  1. 若存在度>3的点,必然发散
  2. 若一个连通子图恰好是一个大小为 k k k的链,则这个连通子图变化 k k k次后必然变成没有贡献的分量
  3. 若一个连通子图恰好是一个大小为 k k k的环,则这个连通子图的贡献即为 k k k
  4. 特判恰好有一个度为3的点的情况
  5. 非上述2,3,4情况的,必然发散

求完每个点的度之后遍历每个子图即可,时间复杂度 O ( n + m ) O(n+m) O(n+m)

T i p s Tips Tips(附:判断一个联通子图正好为链或正好为环的办法)

b l o blo blo表示这个连通子图的大小(点数)

  1. 当入度恰好为2的有 b l o − 2 blo-2 blo2个,入度为1的恰好有2个时,这是链,贡献为0
  2. 当入度恰好为2的有 b l o blo blo个时,这是环,贡献为 b l o blo blo
  3. 在第二点的基础上,如果此时 b l o blo blo的大小大于3,则该连通子图最终一定发散, b r e a k break break
  4. 至于入度恰好为3,判断 b l o blo blo是否正好4个(即菊花图),是的话贡献为3,否则没有贡献
#include<cctype>
#include<cstdio>
#define LL long long
#define N 100010
using namespace std;int n,m,x,y,tot,l[N],vis[N],rd1,rd2,rd3,ans,blo,rd[N];
struct node{int next,to;}e[N<<1];
inline void add(int u,int v){e[++tot]=(node){l[u],v};l[u]=tot;return;}
inline LL read()
{
	char c;LL d=1,f=0;
	while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
	while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
	return d*f;
}
inline void dfs(int x,int col)
{
	vis[x]=col;blo++;
	if(rd[x]==1) rd1++;
	if(rd[x]==2) rd2++;
	if(rd[x]==3) rd3++;
	for(register int i=l[x];i;i=e[i].next)
	{
		int y=e[i].to;
		if(vis[y]) continue;
		dfs(y,col);
	}
	return;
}
signed main()
{
	n=read();m=read();
	for(register int i=1;i<=m;i++)
	{
		x=read();y=read();
		add(x,y);add(y,x);
		rd[x]++;rd[y]++;
	}
	for(register int i=1;i<=n;i++) if(rd[i]>3) return puts("-1")&0;
	for(register int i=1;i<=n;i++)
	{
		if(vis[i]) continue;
		rd1=0;rd2=0;blo=0;rd3=0;
		dfs(i,i);
		if(rd1==2&&rd2==blo-2) continue;
		if(rd3)
		{
			if(blo==4) ans+=3;
			else return puts("-1")&0;
		}
		if(rd2==blo) ans+=blo;
		else if(rd2&&blo>3) return puts("-1")&0;
	}
	printf("%d",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值