Codeforces Round #465

A. Fafa and his Company

方法:暴力枚举leader的个数即可

code:

 1 /*
 2  by skydog
 3  */
 4 #include <iostream>
 5 #include <cstdio>
 6 #include <vector>
 7 #include <utility>
 8 #include <algorithm>
 9 #include <cmath>
10 #include <cstring>
11 #include <map>
12 #include <set>
13 #include <stack>
14 #include <queue>
15 #include <deque>
16 #include <cassert>
17 #include <list>
18 using namespace std;
19 typedef long long ll;
20 typedef pair<int, int> ii;
21 typedef pair<ll, ll> l4;
22
23 #define mp make_pair
24 #define pb push_back
25 #define db(x) cerr << #x << " = " << x << endl
26
27
28 int main()
29 {
30     int n;
31     scanf("%d", &n);
32     int ans = 0;
33     for (int i = 1; i < n; ++i)
34         if ((n-i)%i == 0)
35             ++ans;
36     printf("%d\n", ans);
37 }

B. Fafa and the gates

方法:暴力模拟

code:

 1 /*
 2  by skydog
 3  */
 4 #include <iostream>
 5 #include <cstdio>
 6 #include <vector>
 7 #include <utility>
 8 #include <algorithm>
 9 #include <cmath>
10 #include <cstring>
11 #include <map>
12 #include <set>
13 #include <stack>
14 #include <queue>
15 #include <deque>
16 #include <cassert>
17 #include <list>
18 using namespace std;
19 typedef long long ll;
20 typedef pair<int, int> ii;
21 typedef pair<ll, ll> l4;
22
23 #define mp make_pair
24 #define pb push_back
25 #define db(x) cerr << #x << " = " << x << endl
26
27
28 int n;
29 const int maxn = 1e5+1;
30 char s[maxn];
31 int get(int x, int y)
32 {
33     if (x == y)
34         return 0;
35     if (x > y)
36         return 1;
37     else
38         return -1;
39 }
40
41 int main()
42 {
43     scanf("%d %s", &n, s);
44     int cur = 0, ans = 0;
45     int x = 0, y = 0;
46     for (int i = 0; i < n; ++i)
47     {
48         if (s[i] == ‘U‘)
49             ++y;
50         else
51             ++x;
52         int tmp = get(x, y);
53         if (tmp)
54         {
55             if (tmp == -cur)
56             {
57                 ++ans;
58             }
59             cur = tmp;
60         }
61     }
62     printf("%d\n", ans);
63 }

C. Fifa and Fafa

题意:给你一个圆和一个点,让你在给定圆内画一个圆,使得答案圆不能包含给定点,而且使得给定圆没有被答案圆覆盖的面积最小。给出答案圆的圆心和半径即可。

观察:给定圆没有被覆盖的面积最小,即使答案圆面积最大。如果给定点在给定圆之外,那么答案圆等于给定圆。如果给定点在给定圆之内,只需特判一下给定点和圆心重合的情况,剩下的情况,答案圆可以被唯一确定,即作给定点到给定圆圆心的射线,交给定圆与一交点。以交点和给定点之间线段为直径的圆就是答案。

code:

 1 /*
 2  by skydog
 3  */
 4 #include <iostream>
 5 #include <cstdio>
 6 #include <vector>
 7 #include <utility>
 8 #include <algorithm>
 9 #include <cmath>
10 #include <cstring>
11 #include <map>
12 #include <set>
13 #include <stack>
14 #include <queue>
15 #include <deque>
16 #include <cassert>
17 #include <list>
18 using namespace std;
19 typedef long long ll;
20 typedef pair<int, int> ii;
21 typedef pair<ll, ll> l4;
22
23 #define mp make_pair
24 #define pb push_back
25 #define db(x) cerr << #x << " = " << x << endl
26
27
28 ll r, x1, yy1, x2, y2;
29 ll dis()
30 {
31     ll dx = x1-x2, dy = yy1-y2;
32     return dx*dx + dy*dy;
33 }
34 void end(double x, double y, double r)
35 {
36     printf("%.6lf %.6lf %.6lf\n", x, y, r);
37     exit(0);
38 }
39 int main()
40 {
41     scanf("%lld %lld %lld %lld %lld", &r, &x1, &yy1, &x2, &y2);
42     if (dis() >= r*r)
43         end(x1, yy1, r);
44     if (dis() == 0)
45         end(x1+r/2.0, yy1, r/2.0);
46     double R = (sqrt(dis())+r)/2.0;
47     double dx = (x1-x2), dy = (yy1-y2);
48     dx *= R/sqrt(dis()), dy *= R/sqrt(dis());
49     end(x2+dx, y2+dy, R);
50
51
52 }

D. Fafa and Ancient Alphabet

题意:给你两个长度为n的字符串a, b,字母表大小是m,1 <= n, m <= 1e5。字符串中有一些字符是问号。让你把问好替换成字母表中的数字,问你有多少种方法可以是第一个字符串的字典序大于第二个。

观察:一位一位的讨论即可。

code:

 1 /*
 2  by skydog
 3  */
 4 #include <iostream>
 5 #include <cstdio>
 6 #include <vector>
 7 #include <utility>
 8 #include <algorithm>
 9 #include <cmath>
10 #include <cstring>
11 #include <map>
12 #include <set>
13 #include <stack>
14 #include <queue>
15 #include <deque>
16 #include <cassert>
17 #include <list>
18 using namespace std;
19 typedef long long ll;
20 typedef pair<int, int> ii;
21 typedef pair<ll, ll> l4;
22
23 #define mp make_pair
24 #define pb push_back
25 #define db(x) cerr << #x << " = " << x << endl
26
27 const int mod = 1e9+7;
28 ll power(ll base, ll p)
29 {
30     ll ret = 1;
31     while (p)
32     {
33         if (p&1)
34             ret = ret * base % mod;
35         base = base * base % mod;
36         p >>= 1;
37     }
38     return ret;
39 }
40 const int maxn = 1e5+1;
41 int n, m;
42 ll p[maxn<<1];
43 int a[2][maxn];
44 int main()
45 {
46     scanf("%d %d", &n, &m);
47     int tot = 0;
48     for (int i = 0; i < 2; ++i)
49         for (int j = 0; j < n; ++j)
50             scanf("%d", &a[i][j]), tot += !a[i][j];
51     p[0] = 1;
52     for (int i = 1; i < maxn*2; ++i)
53         p[i] = p[i-1] * m % mod;
54     ll ans = 0;
55     ll base = 1;
56     ll cnt = 0;
57     for (int i = 0; i < n; ++i)
58     {
59         cnt += !a[0][i];
60         cnt += !a[1][i];
61         if (!a[0][i] && !a[1][i])
62         {
63             ans = (ans + base * p[tot-cnt] % mod * (1ll * m * (m-1) / 2 % mod) % mod) % mod;
64             base = base * m % mod;
65         }
66         else if (!a[0][i])
67         {
68             ans = (ans + base * p[tot-cnt] % mod * (m-a[1][i]) % mod) % mod;
69         }
70         else if (!a[1][i])
71         {
72             ans = (ans + base * p[tot-cnt] % mod * (a[0][i]-1) % mod) % mod;
73         }
74         else if (a[0][i] > a[1][i])
75         {
76             ans = (ans + base * p[tot-cnt] % mod) % mod;
77             break;
78         }
79         else if (a[0][i] < a[1][i])
80         {
81             break;
82         }
83     }
84     ans = ans * power(p[tot], mod-2) % mod;
85     printf("%lld\n", ans);
86 }

E. Fafa and Ancient Mathematics

题意:定义合法表达式:一个单数位的正整数(即1-9)是一个合法的表达式。对于任意两个表达式E1和E2,(E1+E2), (E1-E2)都是合法的表达式。下面给你一个长度不超过1e4的表达式,其中所有运算符号(即+和-)都被替换成了?。又告诉你这些问号中,p个是+,剩下的n个是-,min(p, n) <= 100。让你输出表达式最大可能的值。

观察:可以发现表达式是一颗二叉树。很容易想到一个dp,maxi[cur][cnt+][cnt-]((mini[cur][cnt+][cnt-])表示在cur表达式中,或者说cur表达式对应的子树中,填cnt+个+和cnt-个-,能得到的最大值(最小值)。因为题目保证min(p, n) <= 100,而且是二叉树,所以可以把总数量较小的符号记入状态,比如p <= n, maxi[cur][cnt] /mini[cur][cnt],表示cur子树中填cnt个加号能得到的最大值/最小值。计算maxi[cur][cnt]/mini[cur][cnt] 只需要枚举左右子树内的加号个数,和中间符号是+还是-就好了。

code:

  1 /*
  2  by skydog
  3  */
  4 #include <iostream>
  5 #include <cstdio>
  6 #include <vector>
  7 #include <utility>
  8 #include <algorithm>
  9 #include <cmath>
 10 #include <cstring>
 11 #include <map>
 12 #include <set>
 13 #include <stack>
 14 #include <queue>
 15 #include <deque>
 16 #include <cassert>
 17 #include <list>
 18 using namespace std;
 19 typedef long long ll;
 20 typedef pair<int, int> ii;
 21 typedef pair<ll, ll> l4;
 22
 23 #define mp make_pair
 24 #define pb push_back
 25 #define db(x) cerr << #x << " = " << x << endl
 26
 27 const int maxn = 1e4+1;
 28 char s[maxn];
 29 int sz = 0, ptr = 0;
 30 vector<int> g[maxn];
 31 const int maxp = 101;
 32 int maxi[maxn][maxp];
 33 int mini[maxn][maxp];
 34 int v[maxn];
 35 int p, m;
 36 bool isp;
 37 inline void Max(int &a, int b)
 38 {
 39     if (a < b) a = b;
 40 }
 41 inline void Min(int &a, int b)
 42 {
 43     if (a > b) a = b;
 44 }
 45 int dfs(int cur)
 46 {
 47     fill(maxi[cur], maxi[cur]+maxp, -1e5);
 48     fill(mini[cur], mini[cur]+maxp, 1e5);
 49     if (isdigit(s[ptr]))
 50     {
 51         v[cur] = s[ptr]-‘0‘;
 52         ++ptr;
 53         maxi[cur][0] = mini[cur][0] = v[cur];
 54         return 0;
 55     }
 56     assert(s[ptr] == ‘(‘);
 57     ++ptr;
 58     int lhs, rhs, ret = 1;
 59     g[cur].pb(++sz);
 60     ret += dfs(lhs = sz);
 61     assert(s[ptr] == ‘?‘);
 62     ++ptr;
 63     g[cur].pb(++sz);
 64     ret += dfs(rhs = sz);
 65     assert(s[ptr] == ‘)‘);
 66     ++ptr;
 67     if (isp)
 68     {
 69         //limited positive
 70         for (int tot = 1; tot < maxp; ++tot)
 71         {
 72             //pick mid to be positive
 73             for (int i = 0; i <= tot-1; ++i)
 74             {
 75                 Max(maxi[cur][tot], maxi[lhs][i]+maxi[rhs][tot-1-i]);
 76                 Min(mini[cur][tot], mini[lhs][i]+mini[rhs][tot-1-i]);
 77             }
 78         }
 79         for (int tot = 0; tot < maxp; ++tot)
 80         {
 81             //pick mid to be negative
 82             for (int i = 0; i <= tot; ++i)
 83             {
 84                 Max(maxi[cur][tot], maxi[lhs][i]-mini[rhs][tot-i]);
 85                 Min(mini[cur][tot], mini[lhs][i]-maxi[rhs][tot-i]);
 86             }
 87         }
 88     }
 89     else
 90     {
 91         //limited negative
 92         for (int tot = 0; tot < maxp; ++tot)
 93         {
 94             //pick mid to be positive
 95             for (int i = 0; i <= tot; ++i)
 96             {
 97                 Max(maxi[cur][tot], maxi[lhs][i]+maxi[rhs][tot-i]);
 98                 Min(mini[cur][tot], mini[lhs][i]+mini[rhs][tot-i]);
 99             }
100         }
101         for (int tot = 1; tot < maxp; ++tot)
102         {
103             //pick mid to be negative
104             for (int i = 0; i <= tot-1; ++i)
105             {
106                 Max(maxi[cur][tot], maxi[lhs][i]-mini[rhs][tot-1-i]);
107                 Min(mini[cur][tot], mini[lhs][i]-maxi[rhs][tot-1-i]);
108             }
109         }
110     }
111     return ret;
112 }
113 int main()
114 {
115     scanf("%s %d %d", s, &p, &m);
116     isp = p <= m;
117     sz = 1;
118     ptr = 0;
119     assert(dfs(1) == p+m);
120
121     printf("%d\n", maxi[1][min(p, m)]);
122 }

WA:+和-写反。dp时候直接按照最大值枚举就好了,不需要特殊处理。

原文地址:https://www.cnblogs.com/skyette/p/8454753.html

时间: 2024-10-02 02:53:00

Codeforces Round #465的相关文章

Codeforces Round #465 (Div. 2) ABCD

A. Fafa and his Company Fafa owns a company that works on huge projects. There are n employees in Fafa's company. Whenever the company has a new project to start working on, Fafa has to divide the tasks of this project among all the employees. Fafa f

Codeforces Round #465 &amp;935C. Fifa and Fafa计算几何

传送门 题意:在平面中,有一个圆,有一个点,问能在这个圆中围出最大的圆的圆心坐标和半径.要求这个最大圆不包含这个点. 思路:比较基础的计算几何,要分三种情况,第一种就是这个点在圆外的情况.第二种是点在圆内.第三种是这个点和圆心重合. ac代码 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #includ

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp

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 #400 C 前缀和,思维

ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) C. Molly's Chemicals 题意:n个数,问有多少个区间的和是k的次方数,即sum([l, r])=k^x, x>=0. abs(k)<=10. tags:一开始O(n^2)统计,果然炸了.. 这题要在统计到第 i 个数时,看s[i]-k^x是否在前面出现过.因为k指数增长很快,这样就是O(n). // #400 #include<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倍关系或者消除