专栏文章

国庆day2考试总结--下午

个人记录参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@minovhl5
此快照首次捕获于
2025/12/02 05:56
3 个月前
此快照最后确认于
2025/12/02 05:56
3 个月前
查看原文

前言

芭比Q了

problem A

模板题,但是我没有写对,原因是我没有判断<C和判断-1时条件出错

problem.A 正确代码

CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6+5;
struct node
{
	int x,y,w;
}e[N];
bool cmp(node e,node b)
{
	return e.w<b.w;
}
int fa[N],x[N],y[N];
int find(int x)
{
	if(fa[x]==x)return x;
	return fa[x]=find(fa[x]);
}
void unionn(int x,int y)
{
	x=find(x),y=find(y);
	if(x==y)return ;
	fa[x]=y; 
}
int n,k,cnt;
void kruskal()
{
	sort(e+1,e+1+cnt,cmp);
	int ans=0,sum=0;
	for(int i=1;i<=cnt;i++)
	{
		if(find(e[i].x)==find(e[i].y))continue;
		unionn(e[i].x,e[i].y);
		ans++;
		sum+=e[i].w;
	}
	if(ans<n-1)cout<<"-1"; 
	else cout<<sum;
}
signed main()
{
	cin>>n>>k;
	for(int i=1;i<=n;i++)fa[i]=i;
	for(int i=1;i<=n;i++)
	{
		cin>>x[i]>>y[i];
		int nx=x[i],ny=y[i];
		for(int j=1;j<i;j++)
		{
			int zx=x[j],zy=y[j];
			int ans=(nx-zx)*(nx-zx)+(ny-zy)*(ny-zy);
			if(ans>=k)
			{
				cnt++;
				e[cnt].x=i;
				e[cnt].y=j;
				e[cnt].w=ans;
			}
		}
	}
	kruskal();
	return 0;
 }

problem B

依旧模板题,但是我忘记在kruskal函数里面把e[i].x和e[i].y合并了
CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5;
int fa[N],x[N],y[N],n;
struct node
{
	int x,y,w;
}e[N];
bool cmp(node a,node b)
{
	return a.w<b.w;
}
int find(int x)
{
	if(fa[x]==x)return fa[x];
	return fa[x]=find(fa[x]);
}
void unionn(int x,int y)
{
	x=find(x),y=find(y);
	if(x==y)return ;
	fa[x]=y;
	return ;
}
int cnt;
void kruskal()
{
	sort(e+1,e+1+cnt,cmp);
	int ans=0,sum=0;
	for(int i=1;i<=cnt;i++)
	{
		int x=find(e[i].x),y=find(e[i].y);
		if(x==y)continue;
		ans++;
		unionn(e[i].x,e[i].y);
		sum=e[i].w;	
	}
	cout<<sum;
	return ;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)fa[i]=i;
	for(int i=1;i<=n;i++)cin>>x[i]>>y[i];
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{ 
			if(i==j)continue;
			cnt++;
			e[cnt].x=i;
			e[cnt].y=j;
			e[cnt].w=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
		}
	}
	kruskal();
	return 0;
}

problem C

主要是数组原因,然后就是vector push和size求错(下次肯定用数组),再加上输出是<号少写了一个导致CE,其他都想得一摸一样

problem C 正确代码

CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=4e6+5,M=2005;
int fa[M],a[M],b[M],x[M],y[M],c[M],k[M],n,cnt;
struct node
{
	int x,y,w,id;
}e[N];
bool cmp(node a,node b)
{
	return a.w<b.w;
}
int find(int x)
{
	if(fa[x]==x)return fa[x];
	return fa[x]=find(fa[x]);
}
void unionn(int x,int y)
{
	x=find(x),y=find(y);
	if(x==y)return ;
	fa[x]=y;
}
int m;
void kruskal()
{
	for(int i=0;i<=n;i++)fa[i]=i;
	sort(e+1,e+1+m,cmp);
	int sum=0,cnt=0,num=0,l=0,r=0,ans=0;
	for(int i=1;i<=m;i++)
	{
		int x=find(e[i].x),y=find(e[i].y);
		if(x==y)continue;
		unionn(x,y);
		if(e[i].x==0)a[++l]=e[i].y;
		else b[++r]=e[i].x,c[r]=e[i].y;
		sum+=e[i].w;
		cnt++;
		if(cnt>n-1)break;
	}
	cout<<sum<<"\n";
	cout<<l<<"\n";
	for(int i=1;i<=l;i++)cout<<a[i]<<" ";
	cout<<'\n';
	cout<<r<<"\n";
	for(int i=1;i<=r;i++)cout<<b[i]<<" "<<c[i]<<"\n";
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)cin>>x[i]>>y[i];
	for(int i=1;i<=n;i++)cin>>c[i];
	for(int i=1;i<=n;i++)cin>>k[i];
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(i==j)continue;
			int d=abs(x[i]-x[j])+abs(y[i]-y[j]);
			e[++m]=node{i,j,d*(k[i]+k[j]),0};
		}
	}
	for(int i=1;i<=n;i++){
		m++;
		e[m].x=0;
		e[m].y=i;
		e[m].w=c[i];
		e[m].id=i;
	}
	kruskal();
	return 0;
}

problem D

试了一下用贪心能拿35分(甚至还高,但是我只拿了35),正确解法最容易想的是prim,但是没学,所以只能用kruskal,看完题目,连通块需要是一片连续的,所以我们尽量把它向右合并,让它的根节点在区间右侧,那么遍历的时候就能快速的访问区间内的所有连通块

END(AFO了)

评论

0 条评论,欢迎与作者交流。

正在加载评论...