7-9 排座位
1.题意
有n个人,m对关系,1代表这两人是朋友,-1代表这两人是敌人,朋友的朋友是朋友,但朋友的敌人不一定是敌人,敌人的敌人也不一定是朋友,给定k对人,输出他们之间的关系。如果两人之间是朋友,且没有敌对关系,则输出No problem;如果他们之间并不是朋友,但也不敌对,则输出OK;如果他们之间有敌对,然而也有共同的朋友,则输出OK but...;如果他们之间只有敌对关系,则输出No way。
2.题解
用二维数组保存两人之间的直接关系,因为朋友的朋友是朋友,用并查集即可。
3.代码
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int maxn = 1e3 + 5; 5 int f[maxn]; 6 int di[maxn][maxn]; 7 int find(int k) { 8 if(f[k] == k) { 9 return k; 10 } 11 return f[k] = find(f[k]); 12 } 13 void merge(int a, int b) { 14 int fa = find(a); 15 int fb = find(b); 16 if(fa != fb) { 17 f[fa] = fb; 18 } 19 } 20 int n, m, k; 21 int main(){ 22 cin >> n >> m >> k; 23 for(int i = 1; i <= n; i++) { 24 f[i] = i; 25 } 26 27 int a, b, c; 28 for(int i = 1; i <= m; i++) { 29 cin >> a >> b >> c; 30 di[a][b] = c; 31 di[b][a] = c; 32 if(c == 1) { 33 merge(a, b); 34 } 35 } 36 int x, y; 37 while(k--) { 38 cin >> x >> y; 39 if(di[x][y] == 1) { 40 cout << "No problem" << endl; 41 } 42 else if(di[x][y] == -1) { 43 if(find(x) == find(y)) { 44 cout << "OK but..." << endl; 45 } 46 else { 47 cout << "No way" << endl; 48 } 49 }else{ 50 if(find(x) == find(y)) { 51 cout << "No problem" << endl; 52 } 53 else { 54 cout << "OK" << endl; 55 } 56 } 57 } 58 59 return 0; 60 }
7-11 重排链表
1.题意
给定一个单链表 L1→L2→⋯→Ln−1→Ln,请编写程序将链表重新排列为 Ln→L1→Ln−1→L2→⋯。例如:给定L为1→2→3→4→5→6,则输出应该为6→1→5→2→4→3。
2.题解
用结构体数组存结点的数据和下一个结点的地址,两个整型数组存重排前后的地址,注意下末尾输出。
3.代码
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const int maxn = 1e5 + 5; 5 struct node { 6 int data; 7 int next; 8 }li[maxn]; 9 int n,fi; 10 int add1[maxn] = {0}; 11 int add2[maxn] = {0}; 12 int main(){ 13 scanf("%d%d", &fi, &n); 14 int v, ad1, ad2; 15 for(int i = 0; i < n; i++) { 16 scanf("%d%d%d", &ad1, &v, &ad2); 17 li[ad1].data = v; 18 li[ad1].next = ad2; 19 } 20 21 int k = 0; 22 while(fi != -1) { 23 add1[k++] = fi; 24 fi = li[fi].next; 25 } 26 int length = k; 27 k = 0; 28 29 for(int i = 0, j = length - 1; i <= j; ) { 30 if(i == j) { 31 add2[k] = add1[i]; 32 } 33 else { 34 add2[k++] = add1[j--]; 35 add2[k++] = add1[i++]; 36 } 37 } 38 39 for(int i = 0; i < length - 1; i++) { 40 printf("%05d %d %05d ", add2[i], li[add2[i]].data, add2[i + 1]); 41 } 42 printf("%05d %d -1 ", add2[length - 1], li[add2[length - 1]].data); 43 44 return 0; 45 }
7-12 分而治之
1.题意
有n个城市和m条将两个城市连接的道路,消灭指定k个城市,问是否能使所有城市孤立无援。
2.题解
用二维数组存两个城市之间的连通关系,一个数组记录城市的存在与否,将指定的k个城市消灭后,遍历m条道路,看是否还连通。
3.代码
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 int n, m; 5 int city[10005], arr[10005][2]; 6 int main(){ 7 scanf("%d%d", &n, &m); 8 int a, b; 9 for(int i = 0; i < m; i++) { 10 scanf("%d%d", &a, &b); 11 arr[i][0] = a; 12 arr[i][1] = b; 13 } 14 15 int k; 16 scanf("%d", &k); 17 for(int i = 0; i < k; i++) { 18 int flag = 1; 19 for(int i = 1; i <= n; i++) { 20 city[i] = 1; 21 } 22 int t, d; 23 scanf("%d", &t); 24 for(int j = 0; j < t; j++) { 25 scanf("%d", &d); 26 city[d] = 0; 27 } 28 for(int j = 0; j < m; j++) { 29 if(city[arr[j][0]] == 1 && city[arr[j][1]] == 1){ 30 flag = 0; 31 printf("NO "); 32 break; 33 } 34 } 35 if(flag == 1) { 36 printf("YES "); 37 } 38 } 39 40 return 0; 41 }