链接: 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;
}