B
链接:https://www.nowcoder.net/acm/contest/76/B
来源:牛客网
题目描述
随着如今社会的不断变化,交通问题也变得越来越重要,所以市长决定建设一些公路来方便各个城市之间的贸易和交易。虽然市长的想法很好,但是他也遇到了一般人也经常头疼的问题,那就是手头的经费有限……在规划过程中,设计师们已经预算出部分城市之间建设公路的经费需求。现在市长想知道,它能不能将他的m个城市在有限的经费内实现公路交通。如果可以的话,输出Yes,否则输出No(两个城市不一定要直接的公路相连,间接公路到达也可以。)
输入描述:
测试输入包含多条测试数据
每个测试数据的第1行分别给出可用的经费c(<1000000),道路数目n(n<10000),以及城市数目m(<100)。
接下来的n行给出建立公路的成本信息,每行给出三个整数,分别是相连的两个城市v1、v2(0<v1,v2<=m)以及建设公路所需的成本h(h<100)。
输出描述:
对每个测试用例,输出Yes或No。
示例1
输入
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
示例2
输入
10 2 2 1 2 5 1 2 15
输出
Yes
备注:
两个城市之间可能存在多条线路
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; const int moder = 1e9 + 7; const int MAX_V = 510; int cost[MAX_V][MAX_V]; //cost[u][v]表示边e=(u,v)的权值(不存在的情况下设为INF) int mincost[MAX_V]; //从集合X出发的每个变得最小权值 bool used[MAX_V]; //顶点i是包含在集合X中 int V; //顶点数 int prim(){ for(int i = 0;i < V;i ++){ //初始化 mincost[i] = INF; used[i] = false; } mincost[0] = 0; int res = 0; while(true){ int v = -1; for(int u = 0;u < V;u ++){ //从不属于X的顶点中选取从X到其权值最小的顶点 if(!used[u] && (v == -1 || mincost[u] < mincost[v])) v = u; } if(v == -1) break; used[v] = true; //把顶点v加入到X res += mincost[v]; //把权值加上* for(int u = 0;u < V;u ++){ mincost[u] = min(mincost[u], cost[v][u]); } } return res; } int main() { int c,n; while(cin >> c >> n >> V) { int x,y,z; memset(cost,INF, sizeof(cost)); for(int i=0;i < n;i++) { cin >> x >> y >> z; if(z < cost[x-1][y-1]) { cost[x-1][y-1] = z; } } int res = prim(); if(res > c) cout << "No" << endl; else cout << "Yes" << endl; } return 0; }
最小生成树,醉了,第一次写错了竟然也AC了,这数据有多弱。
C
链接:https://www.nowcoder.net/acm/contest/76/C
来源:牛客网
题目描述
给你两个升序排列的集合,求出两个集合的交集。
输入描述:
有多个测试用例,输入到文件结束。
对于每一个测试用例:
第一行输入两个整数n,m(0<n,m<=1000000),分别代表第一个集合和第二个集合的元素的数量。
第二行输入n个整数,表示第一个集合中的元素,元素之间用空格隔开。
第三行输入m个整数,表示第二个集合中的元素,元素之间用空格隔开。
两个集合中的元素范围在[-1000000000,1000000000]区间内。
输出描述:
每个测试用例用一行来输出两个集合的交集的所有元素(元素用空格隔开且按升序排列),若交集为空则输出"empty"。
示例1
输入
2 3 1 3 1 2 3
输出
1 3
备注:
交集为空的情况下,输出"empty"
。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int moder = 1e9 + 7; ll a[1000005]; ll b[1000005]; int main() { ll n,m; while(scanf("%lld%lld",&n,&m) == 2) { for(int i=0;i < n;i++) scanf("%lld",&a[i]); for(int i=0;i < m;i++) scanf("%lld",&b[i]); vector<ll>vc; int x,y; int flag = 0; for (int i = 0; i < n; i++) { for(int j=0;j < m;j++) { if(a[i] == b[j]) { x = i; y = j; flag = 1; goto jo; } } } jo:; if(flag == 0) cout << "empty" << endl; else { while(x < n&&y < m) { if(a[x] < b[y]) x++; if(a[x] > b[y]) y++; else { vc.push_back(a[x]); x++; y++; } } for(int i=0;i < vc.size()-1;i++) printf("%lld ",vc[i]); printf("%lld\n",vc[vc.size()-1]); } } return 0; }
复杂度为n的算法
F
链接: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
示例2
输入
4 3 1 2 2 3 4 1
输出
No
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int moder = 1e9 + 7; struct node { int x; int y; int z; }; int main() { int n,m; while(cin >> n >> m) { int flag = 0; node cnt[m]; for(int i=0;i < m;i++) { cin >> cnt[i].x >> cnt[i].y; cnt[i].z = 0; } int temp = 1; for(int j=0;j < m;j++) { for(int i=0;i < m;i++) { if(cnt[i].x == temp && cnt[i].z == 0) { cnt[i].z = 1; if(cnt[i].y == n) { flag = 1; goto jo; } else { temp = cnt[i].y; } } } } jo:; if(flag == 1) cout << "Yes" << endl; else cout << "No" << endl; } return 0; }
H
题目描述
老李见和尚赢了自己的酒,但是自己还舍不得,所以就耍起了赖皮,对和尚说,光武不行,再来点文的,你给我说出来1-8的全排序,我就让你喝,这次绝不耍你,你能帮帮和尚么?
输入描述:
无
输出描述:
1~8的全排列,按照全排列的顺序输出,每行结尾无空格。
示例1
输入
No_Input
输出
Full arrangement of 1~8
备注:
1~3的全排列 :
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int inf = 0x3f3f3f3f; const int moder = 1e9 + 7; void QPL(int a[],int k,int n) { if(k==n) { for(int i=0;i<n;i++) { cout<<a[i]; if(i != n-1) cout << " "; } cout<<endl; } for(int i=0;i<n;i++) { int isok=1; for(int j=0;j<k;j++) { if(a[j]==i+1) { isok=0; break; } } if(isok==1) { a[k]=i+1; QPL(a,k+1,n); } } } void init(int *a,int n) { for(int i=1;i<=n;i++) a[i-1]=i; } int main() { int a[8]; init(a,8); QPL(a,0,8); return 0; }
-这个博客讲的全排列函数next_permutation蛮好的
int main() { int a[4] = {1,2,3,4}; for(int i=0;i < 4;i++) cout << a[i] <<" "; cout << endl; while(next_permutation(a,a+4)) { for(int i=0;i < 4;i++) cout << a[i] << " "; cout << endl; } return 0; }
很简单,执行一次next_p 就将数组按照字典序向后排序一次,排完以后会返回false