C题:这题说的是套娃,如果做题的时候知道是套娃,那就好理解多了
规则1:套娃A可以放到套娃B里面,当且仅当套娃B没有放在其他套娃里面
规则2:套娃A放在套娃B里面,且套娃B没有放在其他套娃里面,那么可以把A从B中拿出来
问我们最少要操作多少次,才能将套娃全部套起来,拆开和组装都算是一次操作
思路:找到序号为1的套娃的哪一组,然后统计该组有多少个套娃是连在1后面,且每次序号都是加1的,那么这些个套娃是不用拆开的。那么剩下的套娃都是要拆开的
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <algorithm> 5 #include <iostream> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <string> 12 #include <math.h> 13 using namespace std; 14 #pragma warning(disable:4996) 15 typedef long long LL; 16 const int INF = 1<<30; 17 /* 18 19 */ 20 int a[100000 + 10]; 21 int main() 22 { 23 24 int n, k, m; 25 int ans; 26 int cnt; 27 while (scanf("%d%d", &n, &k) != EOF) 28 { 29 ans = cnt = 0; 30 for (int i = 0; i < k; ++i) 31 { 32 scanf("%d", &m); 33 bool flag = false; 34 for (int j = 0; j < m; ++j) 35 { 36 scanf("%d", &a[j]); 37 if (a[j] == 1) 38 { 39 flag = true; 40 } 41 } 42 43 if (flag) 44 { 45 cnt = 1; 46 for (int j = 1; j < m; ++j) 47 { 48 if (a[j] - 1 == a[j - 1]) 49 cnt++; 50 else 51 break; 52 } 53 ans += m - cnt; 54 flag = false; 55 } 56 else 57 ans += m - 1; 58 } 59 ans += n - cnt; 60 printf("%d\n", ans); 61 } 62 return 0; 63 }
D题:当时的想法是把岛屿按距离下一个的岛屿的距离,从小到大排序, 并且将桥的长度也从小到大排序,然后进行贪心, 但是问题是
可能贪心的时候,选择了当前的桥A,但是桥B也时候自己(桥A排在桥B前面), 但是呢,到下一个岛屿的时候,桥B对它来说,太长了。
例子:三个岛屿,两座桥,按上面那样子贪心是不行的。
1 10
11 16
20 23
10 15
上面的贪心策略,没有考虑到的信息是岛屿自身的长度。仅考虑了岛屿与岛屿之间的距离
我们规定上界是:两个岛屿之间能建立的最长的桥, 下界是:最短的桥
我们可以将岛屿按照上界进行排序,然后选择桥的时候,找到第一个大于等于下界的桥即可。这样就不会发生上面所说的那种情况(因为上界是递增的)
还有一点就是STL的lower_bound()函数极端情况下,时间复杂度是O(n),会超时
可以将桥的长度存到set中,然后用set自带的lower_bound()函数, 时间复杂度是O(logn)
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <algorithm> 5 #include <iostream> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <string> 12 #include <math.h> 13 using namespace std; 14 #pragma warning(disable:4996) 15 typedef long long LL; 16 const int INF = 1 << 30; 17 /* 18 19 */ 20 const int N = 200000 + 10; 21 struct Island 22 { 23 LL l, r, upper, lower, id; 24 bool operator<(const Island&rhs)const 25 { 26 return upper < rhs.upper; 27 } 28 }island[N]; 29 set<pair<LL, int> > b; 30 int ans[N]; 31 int main() 32 { 33 int n, m; 34 LL a; 35 scanf("%d%d", &n, &m); 36 for (int i = 0; i < n; ++i) 37 { 38 scanf("%I64d%I64d", &island[i].l, &island[i].r); 39 } 40 for (int i = 0; i < n - 1; ++i) 41 { 42 island[i].id = i; 43 island[i].lower = island[i + 1].l - island[i].r; 44 island[i].upper = island[i + 1].r - island[i].l; 45 } 46 sort(island, island + n - 1); 47 for (int i = 0; i < m; ++i) 48 { 49 scanf("%I64d", &a); 50 b.insert(make_pair(a, i)); 51 } 52 for (int i = 0; i < n - 1; ++i) 53 { 54 set<pair<LL, int> >::iterator iter = b.lower_bound(make_pair(island[i].lower, 0)); 55 if (iter == b.end()) 56 { 57 puts("No"); 58 return 0; 59 } 60 else 61 { 62 if (iter->first <= island[i].upper) 63 { 64 ans[island[i].id] = iter->second + 1; 65 b.erase(iter); 66 } 67 else 68 { 69 puts("No"); 70 return 0; 71 } 72 } 73 } 74 puts("Yes"); 75 printf("%d", ans[0]); 76 for (int i = 1; i < n - 1; ++i) 77 printf(" %d", ans[i]); 78 puts(""); 79 return 0; 80 }
目标:①div2做4题 ②一次AC,手速快,题意看清
时间: 2024-10-12 11:25:37