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