ICPC 2019-2020 North-Western Russia Regional Contest train 补题记录

这篇博客涵盖了三个不同的算法问题,包括在树形结构中寻找等距离点、寻找最小四棱锥包含所有点以及序列元素匹配。第一个问题通过BFS解决,第二个问题通过寻找坐标边界确定最小四棱锥,第三个问题通过unordered_map优化搜索。文章详细解释了解题思路和代码实现,适合进阶的算法学习者参考。
摘要由CSDN通过智能技术生成

A.温暖的签到

 

E. Equidistant

题目大意:给定一颗n节点的树,给定几个点,问我们是否能够在树上找到一点到这几个点的距离是一样的

解题思路:我们把这几个点同时放进去并且进行BFS操作,并且我们开一个数组去记录有几个最终结点到这里的最短路径的的条数,因此对于每个经过的结点,我们若有dis[x] == dis[h] + 1,则cnt[x] += cnt[h],如果dis[x] > dis[h] + 1,则cnt[x] = cnt[h]

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
const int inf = 0x3f3f3f3f;
vector<int> G[maxn];
queue<int> q;
int cnt[maxn];
int dis[maxn];
int n,m;
void BFS()
{
	while(!q.empty())
	{
		int x = q.front();
		q.pop();
		for(int f : G[x])
		{
			if(dis[f] == dis[x] + 1) cnt[f] += cnt[x];
			else if(dis[f] > dis[x] + 1)
			{
				dis[f] = dis[x] + 1;
				cnt[f] = cnt[x];
				q.push(f);
			}
		}
	}
}
void solve()
{
	scanf("%d %d",&n,&m);
	memset(dis,inf,sizeof dis);
	for(int i = 1;i <= n - 1;++i)
	{
		int u,v;
		scanf("%d %d",&u,&v);
		G[u].emplace_back(v);
		G[v].emplace_back(u);
	}
	int pos;
	for(int i = 1;i <= m;++i)
	{
		scanf("%d",&pos);
		dis[pos] = 0;
		cnt[pos] = 1;
		q.push(pos);
	}
	//cout << "??"<<"\n";
	BFS();
	for(int i = 1;i <= n;++i)
	{
		//cout<<i<<" "<< cnt[i] <<"\n";
		if(cnt[i] == m)
		{
			printf("YES\n%d\n",i);
			return;
		}
	}
	printf("NO\n");
}
int main()
{
	solve();
	return 0;
}

I-Ideal Pyramid

题目大意:给定三维空间中的n个点,找出一个最小四棱锥能够将这些点全部包含在锥体里面,并且输出相应顶点的坐标

题目分析:由于这道题目求的是最小的高度,那么我们可以知道必定会存在一根柱子会与金字塔的面相切,那么对于金子塔上面的任意一个点(非顶点)(xi,yi,zi),和其顶点(x,y,z),对于x来说可以列出这样的式子h >=hi + \left | xi - x \right |,那么对于这个绝对值我们也可以进行一个拆分,让式子后面大于等于0,即可获得x的左右边界,同时用这种方法也可以获得y的左右边界,那么最后的点,我们可以知道是(xl + xr >> 1,yl + yr >> 1),对于高度来说,高度是需要取x和y之中长度相对来说比较长的那一根,因此我们也可以输出最后的结果了

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
typedef long long ll;
const ll inf = 0x3f3f3f3f3f3f3f3f;

ll xr = - inf,xl = inf,yr = - inf,yl = inf;
ll x,y,h;
int n;
int main()
{
	scanf("%d",&n);
	for(int i = 1;i <= n;++i)
	{
		scanf("%lld %lld %lld",&x,&y,&h);
		xr = max(h + x,xr);
		xl = min(x - h,xl);
		yr = max(h + y,yr);
		yl = min(y - h,yl);
	}
	printf("%lld %lld %lld\n",(xr + xl) >> 1,(yl + yr) >> 1,max((xr - xl + 1),(yr - yl + 1)) >> 1);
	return 0;
}

M-Managing Difficulties

题目大意:找到一个序列满足aj - ai = ak - aj

解题思路:先分析数据范围2000,那么n^2的时间复杂度是肯定可以被接受的,那么我们可以先把前面的 2 aj - ai给算出来,最后再去读入进来ak的时候将答案给计算进去(注意使用unordered_map,还有在使用count的时候时间复杂度会比直接查询要来的小)

#include <bits/stdc++.h>
using namespace std;
int T,n;
long long ans;
const int maxn = 2e3 + 10;
int a[maxn];
unordered_map<int,int> mp;
int tmp;
void solve()
{
	scanf("%d",&n);
	ans = 0;
	mp.clear();
	for(int i = 1;i <= n;++i)
	{
		scanf("%d",&a[i]);
		if(mp.count(a[i]) != 0) ans += mp[a[i]];
		for(int j = 1;j < i;++j)
		{
			mp[2 * a[i] - a[j]]++;
		}
	}
	printf("%lld\n",ans);
}
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		solve();
	}
	return 0;
}

J-Just the Last Digit

题目大意:给定一张图,aij代表从i到j的路有aij % 10条

解题思路:分析数据范围,数据范围比较小,那么我们可以直接通过枚举中间那个来判断相对应的路是否符合我们的要求

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e2 + 10;
int mp[maxn][maxn];
char str[maxn][maxn];
int ans[maxn][maxn];
int n;
void solve()
{
	scanf("%d",&n);
	//getchar();
	for(int i = 1;i <= n;++i)
	{
		scanf("%s",str[i] + 1);
	//	printf("%s\n",str[i] + 1);
	}
	for(int i = 1;i <= n;++i)
	{
		for(int j = 1;j <= n;++j)
		{
			//printf("str: %s",str[i]);
			mp[i][j] = str[i][j] - '0';
		}
	}
//	for(int i = 1;i <= n;++i)
//	{
//		for(int j = 1;j <= n;++j)
//		{
//			printf("%d ",mp[i][j]);
//		}
//		printf("\n");
//	}
	for(int k = 1;k <= n;++k)
	{
		for(int i = 1;i <= n - k;i++)
		{
			int f = i + k,cnt = 0;
			for(int j = i + 1;j < f;++j)
			{
				cnt = (cnt + ans[i][j] * mp[j][f]) % 10;
			}
			if(cnt != mp[i][f]) ans[i][f] = 1;
		}
	}
	for(int i = 1;i <= n;++i)
	{
		for(int j = 1;j <= n;++j)
		{
			printf("%d",ans[i][j]);
		} 
		printf("\n");
	}
}
int main()
{
	solve();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值