2018年全国多校算法寒假训练营练习比赛(第四场)BCFH

链接: https://www.nowcoder.net/acm/contest/76/B
来源:牛客网
B 道路建设

题目描述

随着如今社会的不断变化,交通问题也变得越来越重要,所以市长决定建设一些公路来方便各个城市之间的贸易和交易。虽然市长的想法很好,但是他也遇到了一般人也经常头疼的问题,那就是手头的经费有限……在规划过程中,设计师们已经预算出部分城市之间建设公路的经费需求。现在市长想知道,它能不能将他的m个城市在有限的经费内实现公路交通。如果可以的话,输出Yes,否则输出No(两个城市不一定要直接的公路相连,间接公路到达也可以。)

输入描述:

测试输入包含多条测试数据
每个测试数据的第1行分别给出可用的经费c(<1000000),道路数目n(n<10000),以及城市数目m(<100)。
接下来的n行给出建立公路的成本信息,每行给出三个整数,分别是相连的两个城市v1、v2(0<v1,v2<=m)以及建设公路所需的成本h(h<100)。

输出描述:

对每个测试用例,输出Yes或No。
  
  

输入

20 10 5
1 2 6
1 3 3
1 4 4
1 5 5
2 3 7
2 4 7
2 5 8
3 4 6
3 5 9
4 5 2

输出

Yes

题目分析:典型的最小生成树,点少边多,优先选择prim,无坑,唯一要注意的是两城市之间可能存在多条路线


#include<bits/stdc++.h>
using namespace std;
struct qq
{
	int y ,value;
	bool operator < (const qq &a)const
	{
		return value > a.value;
	}
}p,r;
int main()
{
	int c ,n ,m ,x ,y ,h ,ans ,i ,j ,t;
	while(~scanf("%d%d%d",&c,&n,&m))
	{
		int a[m+1][m+1];
		bool visit[m+1];
		memset(visit,false,sizeof(visit));
		memset(a,0,sizeof(a));
		for(i = 0; i < n; i++)
		{
			scanf("%d%d%d",&x,&y,&t);
			if(!a[x][y] || t < a[x][y])
				a[x][y] = t;
		}
		priority_queue<qq> q;
		visit[1] = true;
		for(i = 1; i <= m; i++)
			if(a[1][i])
			{
				p.y = i;
				p.value = a[1][i];
				q.push(p);
			}
		ans = 0;
		i = 1;
		while(1)
		{
			r = q.top(),q.pop();
			if(!visit[r.y])
			{
				visit[r.y] = true;
				ans += r.value;
				for(j = 1; j <= m; j++)
					if(a[r.y][j] && !visit[j])
					{
						p.y = j;
						p.value = a[r.y][j];
						q.push(p);
					}
				i++;
			}
			if(i==m || ans>c)
				break;
		}
		printf(ans<=c ? "Yes\n" : "No\n");
	}
	return 0;
 } 



C 求交集


题目描述

链接: https://www.nowcoder.net/acm/contest/76/C
来源:牛客网

给你两个升序排列的集合,求出两个集合的交集。

输入描述:

有多个测试用例,输入到文件结束。
对于每一个测试用例:
第一行输入两个整数n,m(0<n,m<=1000000),分别代表第一个集合和第二个集合的元素的数量。
第二行输入n个整数,表示第一个集合中的元素,元素之间用空格隔开。
第三行输入m个整数,表示第二个集合中的元素,元素之间用空格隔开。
两个集合中的元素范围在[-1000000000,1000000000]区间内。

输出描述:

每个测试用例用一行来输出两个集合的交集的所有元素(元素用空格隔开且按升序排列),若交集为空则输出"empty"。

输入

2 3
1 3
1 2 3

输出

1 3


题目分析:第一眼看到就想到二分查找,讲第一个集合作为查询数组,第二个集合中的每个元素作为待查询量。偷了个懒,用了STL大笑,真心不错。

还有一种方法:因为两集合有序,故直接走下标即可,两个下标一起走,谁的值小谁往后挪,遇到相等就输出。你可以试试得意

二分查找版:

#include<bits/stdc++.h>
int main()
{
	int n ,m ,t ,i;
	bool isfirst;
	while(~scanf("%d%d",&n,&m))
	{
		int a[n+1];
		isfirst = true;
		a[n] = 2100000000;
		for(i = 0; i < n; i++)
			scanf("%d",&a[i]);
		n++;
		for(i = 0; i < m; i++)
		{
			scanf("%d",&t);
			if(std::binary_search(a,a+n,t))
			{
				if(isfirst)
				{
					printf("%d",t);
					isfirst = false;
				}
				else printf(" %d",t);
			}
		}
		if(isfirst)
			printf("empty");
		printf("\n");
	}
	return 0;
 } 


F Call to your teacher


链接:https://www.nowcoder.net/acm/contest/76/F
来源:牛客网

题目描述

从实验室出来后,你忽然发现你居然把自己的电脑落在了实验室里,但是实验室的老师已经把大门锁上了。更糟的是,你没有那个老师的电话号码。你开始给你知道的所有人打电话,询问他们有没有老师的电话,如果没有,他们也会问自己的同学来询问电话号码。那么,你能联系到老师并且拿到电脑吗。

输入描述:

存在多组测试样例
每组样例的第一行分别是两个整数n(1<n<=50),m(1<m<=2000),n是在题目当中出现的人数,其中你的序号是1号,实验室老师的序号是n。
接下来的m行,每行有两个整数x(1<=x<=n),y(1<=y<=n),代表x有y的电话号码。

输出描述:

对于每组测试样例,如果你最终能联系到老师,输出“Yes”,否则输出“No”。
示例1

输入

5 5
1 3
2 3
3 4
2 4
4 5

输出

Yes


思路:很容易发现是个简单的递归,也可以说是dfs,但要注意打电话不能互相打哦,否则你的栈就会爆掉滴,也就会得到一个内存超限。


#include<bits/stdc++.h>
bool a[51][51] ,lag;
int n ,m;
void dfs(int x)
{
	if(x == n)
	{
		lag = true;
		return;
	}
	for(int i = 1; i <= n; i++)
	{
		if(a[x][i])
			dfs(i);
		if(lag)
			break;
	}
}
int main()
{
	int x ,y ,i;
	while(~scanf("%d%d",&n,&m))
	{
		lag = false;
		memset(a,false,sizeof(a));
		for(i = 0; i < m; i++)
		{
			scanf("%d%d",&x,&y);
			a[x][y] = true;
		}
		dfs(1);
		printf(lag ? "Yes\n" : "No\n");
	}
	return 0;
 } 

H 老子的全排列呢

题目描述:输出1-8的全排列。

1~3的全排列 ,输出格式如下:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

题目分析:赤裸裸的dfs,但是俺用的STL大笑,希望您了解到这个后函数可以帮助你答题更迅速,更简洁哦。

#include<bits/stdc++.h>
int main()
{
	//freopen("d:\\2.txt","w",stdout);
	int a[]={1,2,3,4,5,6,7,8} ;
	do
	{
		printf("%d",a[0]);
		for(int i = 1; i < 8; i++)
			printf(" %d",a[i]);
		printf("\n");
	}while(std::next_permutation(a,a+8));
	return 0;
 } 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值