Codeforces Round #358 (Div. 2)

4/5

又是三题滚粗了,注定是打铁的命~~

题A Alyona and Numbers

题意:给你n和m,找[1, n]和[1,m]范围内的两个数相加,有多少个的和是5的倍数?

题解:枚举x在[1,n]的范围,然后得到范围[x + 1, x + m]的数,求有多少个是5的倍数即可。

 1 /*zhen hao*/
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4
 5 #define lson l, m, rt*2
 6 #define rson m + 1, r, rt*2+1
 7 #define xx first
 8 #define yy second
 9
10 typedef pair<int,int> pii;
11 typedef long long ll;
12 typedef unsigned long long ull;
13
14 int main() {
15 //  freopen("case.in", "r", stdin);
16   int n, m;
17   ll res = 0;
18   cin >> n >> m;
19   for (int i = 1; i <= n; i++) {
20     int l = i + 1, r = i + m;
21     res += (r / 5) - ((l - 1) / 5);
22   }
23   cout << res << endl;
24   return 0;
25 }

代码君

题B Alyona and Mex

题意:给你n个数,让你可以对任意一个数变成小于它的数,然后问你最后这个序列的最小的没有的正整数是多少?

题解:水题,排个序,然后扫一下即可。

 1 /*zhen hao*/
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4
 5 #define lson l, m, rt*2
 6 #define rson m + 1, r, rt*2+1
 7 #define xx first
 8 #define yy second
 9
10 typedef pair<int,int> pii;
11 typedef long long ll;
12 typedef unsigned long long ull;
13
14 const int maxn = 1e5 + 100;
15 int v[maxn];
16
17 int main() {
18 //  freopen("case.in", "r", stdin);
19   int n;
20   cin >> n;
21   for (int i = 0; i < n; i++) {
22     scanf("%d", v + i);
23   }
24   sort(v, v + n);
25   int c = 0;
26   for (int i = 0; i < n; i++) {
27     if (v[i] > c) c++;
28   }
29   cout << c + 1 << endl;
30   return 0;
31 }

代码君

题C Alyona and the Tree

题意:给你n个带权点,然后组成一棵带权树,然后对于一个点u,如果存在子树中的点v使得dist(u,v) >  av,那么这个点为sad点,问你删除最少多少个点使得这棵树没有sad点?

题解:一开始想麻烦了,O(n ^ 2)肯定超时,开始的想法是对于这个点的子树中有多少个不是sad点,然后传上去继续判断,这样就中了出题人的圈套。应该分析的是这个v,而不是u,也就是说对于v的祖先是固定的,这么多祖先中有没有使得自己变sad点的,也就是存不存在u使得满足dist(u,v) >  av,av是固定的,也就是说我们去路径的最大值看一下满不满足,如果最大值都不满足的话,那么一定都可以,这个点就一定不是sad点,标记一下,最后再dfs一下统计个数即可。

 1 /*zhen hao*/
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4
 5 #define lson l, m, rt*2
 6 #define rson m + 1, r, rt*2+1
 7 #define xx first
 8 #define yy second
 9
10 typedef pair<int,int> pii;
11 typedef long long ll;
12 typedef unsigned long long ull;
13
14 const int maxn = 1e5 + 100;
15 int a[maxn], e, head[maxn], flag[maxn];
16
17 struct Edge {
18   int v, w, nx;
19 } edges[maxn * 2];
20
21 void init() {
22   e = 0;
23   memset(head, -1, sizeof head);
24 }
25
26 void add_edge(int u, int v, int w) {
27   edges[e] = (Edge){v, w, head[u]};
28   head[u] = e++;
29 }
30
31 void dfs1(int u, int p, ll d) {
32   for (int i = head[u]; ~i; i = edges[i].nx) {
33     int v = edges[i].v;
34     if (v == p) continue;
35     if (d + edges[i].w > a[v] || edges[i].w > a[v]) flag[v] = 1;
36     else dfs1(v, u, max((ll)edges[i].w, d + edges[i].w));
37   }
38 }
39
40 int dfs2(int u, int p) {
41   if (flag[u]) return 0;
42   int ret = 1;
43   for (int i = head[u]; ~i; i = edges[i].nx) {
44     int v = edges[i].v;
45     if (v == p) continue;
46     ret += dfs2(v, u);
47   }
48   return ret;
49 }
50
51 int main() {
52 //  freopen("case.in", "r", stdin);
53   int n;
54   cin >> n;
55   for (int i = 1; i <= n; i++) {
56     scanf("%d", a + i);
57   }
58   init();
59   for (int i = 2; i <= n; i++) {
60     int u, w;
61     scanf("%d%d", &u, &w);
62     add_edge(i, u, w);
63     add_edge(u, i, w);
64   }
65   dfs1(1, -1, 0);
66   cout << n - dfs2(1, -1) << endl;
67   return 0;
68 }

代码君

题D Alyona and Strings

题意:给你两个串,然后你可以分割s出k个子串,然后这k个子串在t串中出现,且顺序一样,问你这k个串最长是多少?

题解:这题是到水题,由于比赛没时间做,真是可惜了~~。正解是dp,dp(i,j,k)表示s的i,t的j,分割出了k各部分,然后最长是多少?有一个问题,就是想要接着上一个串继续组成k个部分要满足上一个串的最后两个刚好是i-1和j-1,所以这里要再加一维l,0表示最长,1表示以当且字符串结尾的最长,最后转移一下就好了。我觉得可行的还有一种解法就是pres和pret表示匹配的对应的s和t的最后两个位置,也是一样的效果,懒得写了!!

 1 /*zhen hao*/
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4
 5 const int L = 1100, K = 11;
 6 int dp[L][L][K][2];
 7 char s[L], t[L];
 8
 9 int main() {
10 //  freopen("case.in", "r", stdin);
11   int n, m, k;
12   cin >> n >> m >> k >> s >> t;
13
14   for (int i = 1; i <= n; i++)
15     for (int j = 1; j <= m; j++)
16       for (int l = 1; l <= k; l++) {
17         if (s[i - 1] == t[j - 1]) {
18           dp[i][j][l][1] = 1 + max(dp[i - 1][j - 1][l][1], dp[i - 1][j - 1][l - 1][0]);
19         }
20         dp[i][j][l][0] = max(dp[i][j][l][1], max(dp[i - 1][j][l][0], dp[i][j - 1][l][0]));
21       }
22
23   cout << dp[n][m][k][0] << endl;
24   return 0;
25 }

代码君

时间: 2024-10-10 18:31:44

Codeforces Round #358 (Div. 2)的相关文章

Codeforces Round #358 (Div. 2) D. Alyona and Strings(DP)

题目链接:点击打开链接 思路: 类似于LCS, 只需用d[i][j][k][p]表示当前到了s1[i]和s2[j], 形成了k个子序列, 当前是否和上一个字符和上一个字符相连形成一个序列的最长序列和. 细节参见代码: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <string> #include <vector&

Codeforces Round #279 (Div. 2) ABCD

Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name     A Team Olympiad standard input/output 1 s, 256 MB  x2377 B Queue standard input/output 2 s, 256 MB  x1250 C Hacking Cypher standard input/output 1 s, 256 MB  x740 D Chocolate standard input/

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd

Codeforces Round #273 (Div. 2)

Codeforces Round #273 (Div. 2) 题目链接 A:签到,仅仅要推断总和是不是5的倍数就可以,注意推断0的情况 B:最大值的情况是每一个集合先放1个,剩下都丢到一个集合去,最小值是尽量平均去分 C:假如3种球从小到大是a, b, c,那么假设(a + b) 2 <= c这个比較明显答案就是a + b了.由于c肯定要剩余了,假设(a + b)2 > c的话,就肯定能构造出最优的(a + b + c) / 3,由于肯定能够先拿a和b去消除c,而且控制a和b成2倍关系或者消除

Codeforces Round #339 (Div. 2) B. Gena&#39;s Code

B. Gena's Code It's the year 4527 and the tanks game that we all know and love still exists. There also exists Great Gena's code, written in 2016. The problem this code solves is: given the number of tanks that go into the battle from each country, f

Codeforces Round #315 (Div. 1)

A. Primes or Palindromes? time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output Rikhail Mubinchik believes that the current definition of prime numbers is obsolete as they are too complex and un