2020.10.03天梯赛练习
题目:排座位
思路:
这个题直接暴力做就可以了,开个二维数组来存储每对人的状态,后面查询时再找一下数组。这里要注意的是当两个人是敌对关系时,如果有相同的敌人或者朋友是输出 “OK but...”(当时做题时没考虑有共同敌人也输出 “OK but...”,题目没读清楚)。
解题代码:
#include <cstdio> #include <iostream> #include <algorithm> #include <cmath> #include <string> #include <cstring> #include <map> #include <set> using namespace std; const long long N = 1e10 + 7; const int maxn = 2e5 + 5; const long long INF = 8e18; typedef long long ll; map<int,int>ma; #define for0(i,n) for(int i = 0;i < n;i++) #define for1(i,n) for(int i = 1;i <= n;i++) int p[110][110]; int main() { int n,m,x; cin >> n >> m >> x; for(int i = 0;i < m;i++){ int a,b,c; cin >> a >> b >> c; if(a > b) swap(a,b); p[a][b] = c; } for(int i = 0;i < x;i++){ int a,b; cin >> a >> b; if(a > b) swap(a,b); if(p[a][b] == 1){ cout << "No problem" << endl; } if(p[a][b] == 0) cout << "OK" << endl; if(p[a][b] == -1){ int sign = 0; for(int i = a+1;i <= n;i++){ if(p[a][i] * p[b][i] == 1 || p[a][i] * p[i][b] == 1 ){ sign = 1; break; } } if(sign){ cout << "OK but..." << endl; continue; } for(int i = 1;i < a;i++){ if(p[i][a] * p[b][i] == 1 || p[i][a] * p[i][b] == 1 ){ sign = 1; break; } } if(sign){ cout << "OK but..." << endl; continue; } cout << "No way" << endl; } } }
题目:重排链表
思路:
这个题就是一个新的链表排序规则,让你重新排。首先可以用结构体来存储结点的数据和下一个结点的地址,用结构体的下标记录该结点地址。这道题,首先会有无效结点(有一个测试点会卡这一点),所以我们可以再开个数组,来记录一开始链表中结点地址变化顺序,并记录有效结点个数(代码中的num)。通过样例输出,我们可以发现,会发现每一行结束,与下一行开始输出的地址是一样的,这样我们可以想到输出方式,首先把num这一位置的输出,后面通过循环限制输出,保证按照一前一后输出,最后再加上结束地址-1.
解题代码:
#include <cstdio> #include <iostream> #include <algorithm> #include <cmath> #include <string> #include <cstring> #include <map> #include <set> using namespace std; const long long N = 1e10 + 7; const int maxn = 2e5 + 5; const long long INF = 8e18; typedef long long ll; #define for0(i,n) for(int i = 0;i < n;i++) #define for1(i,n) for(int i = 1;i <= n;i++) map<string,int>ma; struct listm{ int date; int next; }l[100010]; int order[100010]; int main() { int star,n,num = 0; cin >> star >> n; for(int i = 0;i < n;i++){ int address; cin >> address; cin >> l[address].date >> l[address].next; } while(star != -1){ order[++num] = star; star = l[star].next; } printf("%05d %d ",order[num],l[ order[num] ].date); for(int i = 2;i <= num;i++){ if(i % 2 == 0) printf("%05d\n%05d %d ",order[i/2],order[i/2],l[ order[i/2] ].date); else printf("%05d\n%05d %d ",order[num - i/2],order[num - i/2],l[ order[num - i/2] ].date); } cout << -1 << endl; return 0; }
题目:分而治之
思路:
可以看到数据并不是很大,可以用数组来存一下每对城市的情况,用一个标记数组来记录是否被攻占。后面先将标记数组初始化为1,后面被攻占后改为0,最后,通过之前记录下来的成对城市,进行遍历判断一遍,看是否有成对的城市还在相连。
解题代码:
#include <cstdio> #include <iostream> #include <algorithm> #include <cmath> #include <string> #include <cstring> #include <map> #include <set> using namespace std; const long long N = 1e10 + 7; const int maxn = 2e5 + 5; const long long INF = 8e18; typedef long long ll; #define for0(i,n) for(int i = 0;i < n;i++) #define for1(i,n) for(int i = 1;i <= n;i++) bool citysign [10010]; int point[10010][2]; int main() { int n,y; cin >> n >> y; for(int i = 0;i < y;i++){ int a,b; cin >> a >> b; point[i][0] = a; point[i][1] = b; } int x; cin >> x; for(int i = 0;i < x;i++){ for(int j = 1;j <= n;j++){ citysign[j] = 1; } int num,sign = 1; cin >> num; for(int j = 0;j < num;j++){ int city; cin >> city; citysign[city] = 0; } for(int j = 0;j < y;j++){ if(citysign[ point[j][0] ] == 1 && citysign[ point[j][1] ] == 1){ sign = 0; break; } } if(!sign) cout << "NO" << endl; else cout << "YES" << endl; } return 0; }
题目:社交集群
思路:
这个题就是用到了并查集,然后用一个数组记录每个人的第一个兴趣,以便后面查询父节点,然后遍历每个人的父节点,用它当作标记数组的下标记录同兴趣人数,标记数组中有多少非0元素便有多少个集合,最后将标记数组排序,输出各个集合人数即可。
解题代码:
#include <cstdio> #include <iostream> #include <algorithm> #include <cmath> #include <string> #include <cstring> #include <map> #include <set> using namespace std; const long long N = 1e10 + 7; const int maxn = 1e4 + 4; const long long INF = 8e18; typedef long long ll; #define for0(i,n) for(int i = 0;i < n;i++) #define for1(i,n) for(int i = 1;i <= n;i++) int setfrist[maxn]; int people[maxn]; int fa[maxn]; bool cmp(int a,int b){ return a > b; } int Find(int x){ if(fa[x] == x) return x; else return fa[x] = Find(fa[x]); } void hebing(int a,int b){ int fx = Find(a),fy = Find(b); if(fx != fy) fa[fx] = fy; } int main(){ for1(i,maxn){ fa[i] = i; } int t; cin >> t; for0(i,t){ int m,temp; scanf("%d: ",&m); cin >> temp; setfrist[i] = temp; for(int j = 1;j < m;j++){ int x; cin >> x; hebing(temp,x); } } int num = 0; for0(i,t){ people[ Find(setfrist[i]) ]++; } for1(i,maxn){ if(people[i]) num++; } sort(people,people+maxn,cmp); cout << num << endl; for(int i = 0;i < num;i++){ if(i != num-1) cout << people[i] << " "; else cout << people[i] << endl; } return 0; }

浙公网安备 33010602011771号