Codeforces Round#310 div2

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

Codeforces Round#310 div2的相关文章

codeforces round #257 div2 C、D

本来应该认真做这场的,思路都是正确的. C题,是先该横切完或竖切完,无法满足刀数要求,再考虑横切+竖切(竖切+横切), 因为横切+竖切(或竖切+横切)会对切割的东西产生交叉份数,从而最小的部分不会尽可能的大. 代码如下,虽然比较长.比较乱,但完全可以压缩到几行,因为几乎是4小块重复的代码,自己也懒得压缩 注意一点,比如要判断最小块的时候,比如9行要分成2份,最小的剩下那份不是9取模2,而应该是4 m/(k+1)<=m-m/(k+1)*k          #include<bits/stdc+

codeforces Round #250 (div2)

a题,就不说了吧 b题,直接从大到小排序1-limit的所有数的lowbit,再从大到小贪心组成sum就行了 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #define N 200000 6 using namespace std; 7 int pos[N],a[N],s[N],f[N],la[N],b[N],i,j,k,ans,n,p

Codeforces Round#320 Div2 解题报告

Codeforces Round#320 Div2 先做个标题党,骗骗访问量,结束后再来写咯. codeforces 579A Raising Bacteria codeforces 579B Finding Team Member codeforces 579C A Problem about Polyline codeforces 579D "Or" Game codeforces 579E Weakness and Poorness codeforces 579F LCS Aga

Codeforces Round #254(div2)A

很有趣的题.想到了就非常简单,想不到就麻烦了. 其实就是一种逆向思维:最后结果肯定是这样子: WBWBWBWB... BWBWBWBW... WBWBWBWB... ... 里面有“-”的地方改成“-”就行了. 但是我开始是正着想的,想每个点怎么处理,这还要看它周围点的状态,越想越麻烦... 这题中体现的正难则反的逆向思维很值得学习. #include<iostream> #include<cstdio> #include<cstdlib> #include<cs

Codeforces Round #254(div2)B

就是看无向图有几个连通块,答案就是2n-num. 范围很小,就用矩阵来存图减少代码量. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<map> #include<set> #include<vector> #include<algorithm> #inc

Codeforces Round #260(div2)C(递推)

有明显的递推关系: f[i]表示i为数列中最大值时所求结果.num[i]表示数i在数列中出现了几次. 对于数i,要么删i,要么删i-1,只有这两种情况,且子问题还是一样的思路.那么很显然递推一下就行了:f[i]=max(f[i-1],f[i-2]+i*num[i]); 这里技巧在于:为了防止麻烦,干脆就所有数的出现次数都记录一下,然后直接从2推到100000(类似于下标排序),就不用排序了,也不用模拟删除操作了.这一技巧貌似简单,但实际上临场想出来也需要点水平. #include<iostrea

Codeforces Round #289 Div2 E

Problem 给一串长度为N的字符串,对于每个字符,若字符为元音,则权值为1,否则为0.一个子串的权值定义为该串所有字符权值之和除以字符个数,一个母串的权值定义为所有子串的权值之和.求母串的权值. Limits Time Limit(ms): 1000 Memory Limit(MB): 256 N: [1, 5*10^5] 字符集: 'A'-'Z' 元音: I E A O U Y Solution 考虑每个元音字符对母串的贡献,可以找出规律. More 举"ABCDOEFGHKMN"

Codeforces Round #403 div2 C. Andryusha and Colored Balloons

题目链接:Codeforces Round #403 div2 C. Andryusha and Colored Balloons 题意: 给你一棵n个节点的树,然后让你染色,规定相连的三个 节点不能同色,问需要的最少颜色,并输出其中一种方案. 题解: 因为只有相邻3个节点不同色. 所以直接DFS,每个节点都从1开始. 然后ans[v]!=ans[u]!=ans[fa]就行. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i&

贪心/思维题 Codeforces Round #310 (Div. 2) C. Case of Matryoshkas

题目传送门 1 /* 2 题意:套娃娃,可以套一个单独的娃娃,或者把最后面的娃娃取出,最后使得0-1-2-...-(n-1),问最少要几步 3 贪心/思维题:娃娃的状态:取出+套上(2),套上(1), 已套上(0),先从1开始找到已经套好的娃娃层数, 4 其他是2次操作,还要减去k-1个娃娃是只要套上就可以 5 详细解释:http://blog.csdn.net/firstlucker/article/details/46671251 6 */ 7 #include <cstdio> 8 #i