2018 Multi-University Training Contest 1 Solution

A - Maximum Multiple

题意:给出一个n 找x, y, z 使得$n = x + y +z$ 并且 $n \equiv 0 \pmod x, n \equiv 0 \pmod y, n \equiv 0 \pmod z$ 并且使得 $x \cdot y \cdot z$ 最大

思路:设$a = \frac{n}{x}, b = \frac{n}{y}, c = \frac{n}{z}$ 那么 $\frac{1}{a} + \frac{1}{b} + \frac{1}{c} = 1$ 那么我们考虑去凑 a, b, c

两种方案  ${3, 3, 3}$  或者 ${2, 4, 4}$ 取max

 1 #include<bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 typedef long long ll;
 6
 7 ll n;
 8
 9 int main()
10 {
11     int t;
12     scanf("%d", &t);
13     while(t--)
14     {
15         scanf("%lld", &n);
16         if(n % 3 == 0)
17         {
18             ll ans = n / 3;
19             ans *= n / 3;
20             ans *= n / 3;
21             printf("%lld\n", ans);
22         }
23         else if(n % 4 == 0)
24         {
25             ll ans = n / 2;
26             ans *= n / 4;
27             ans *= n / 4;
28             printf("%lld\n", ans);
29         }
30         else
31         {
32             puts("-1");
33         }
34     }
35     return 0;
36 }

B - Balanced Sequence

题意:求如何拼接 使得balanced Sequence 最长

思路:首先预处理,使得剩下的串都是 (((    或者 )))   或者 )))(((

((( 这种都放左边  ))) 都放右边  目前的问题就是 )))((( 这种在中间按什么顺序放使得答案最大

我们定义 $L_1, R_1$  $L_2, R_2$ 分别为两个串的左括号数量和右括号数量

假如 1 放在 2前面  那么对答案的贡献是 $min(R_1, L_2)$

假如 1 放在 2 后面 那么对答案的贡献是 $min(R_2, L_1)$

比较对答案的贡献,哪个答案贡献大,选哪种放置方式

如果读答案的贡献一样大,那么我们让左括号多的放前面 因为这样对后面的答案贡献大

Dup4:

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 #define N 100010
 6
 7 struct node
 8 {
 9     int l, r;
10     inline node() {}
11     inline node(int l, int r) : l(l), r(r) {}
12     inline bool operator < (const node &b) const
13     {
14         int t1 = min(l, b.r), t2 = min(r, b.l);
15         return t1 > t2 || (t1 == t2 && (l > b.l));
16     }
17 }arr[N];
18
19 int t, n;
20 char s[N];
21
22 int main()
23 {
24     scanf("%d", &t);
25     while (t--)
26     {
27         int L = 0, R = 0, ans = 0, cnt = 0;
28         scanf("%d", &n);
29         for (int i = 1; i <= n; ++i)
30         {
31             scanf("%s", s);
32             int LL = 0, RR = 0;
33             for (int j = 0, len = strlen(s); j < len; ++j)
34             {
35                 if (s[j] == ‘(‘)
36                     ++LL;
37                 else
38                 {
39                     if (LL)
40                     {
41                         --LL;
42                         ans += 2;
43                     }
44                     else
45                         ++RR;
46                 }
47             }
48             if (LL && RR)
49                 arr[++cnt] = node(LL, RR);
50             else if (LL) L += LL;
51             else R += RR;
52         }
53         sort(arr + 1, arr + 1 + cnt);
54         for (int i = 1; i <= cnt; ++i)
55         {
56             int LL = arr[i].l, RR = arr[i].r;
57             ans += min(L, RR) * 2;
58             L -= min(L, RR);
59             L += LL;
60         }
61         ans += min(L, R) * 2;
62         printf("%d\n", ans);
63     }
64     return 0;
65 }

XHT:

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 #define N 100010
 6
 7 struct node
 8 {
 9     int l, r;
10     inline node() {}
11     inline node(int l, int r) : l(l), r(r) {}
12     inline bool operator < (const node &b) const
13     {
14         if(l >= r && b.l < b.r)
15             return true;
16         if(l < r && b.l >= b.r)
17             return false;
18         if(l >= r && b.l >= b.r)
19             return r < b.r;
20         if(l < r && b.l < b.r)
21             return l > b.l;
22     }
23 }arr[N];
24
25 int t, n;
26 char s[N];
27
28 int main()
29 {
30     scanf("%d", &t);
31     while (t--)
32     {
33         int ans = 0;
34         scanf("%d", &n);
35         for (int i = 1; i <= n; ++i)
36         {
37             scanf("%s", s);
38             int LL = 0, RR = 0;
39             for (int j = 0, len = strlen(s); j < len; ++j)
40             {
41                 if (s[j] == ‘(‘)
42                     ++LL;
43                 else
44                 {
45                     if (LL)
46                     {
47                         --LL;
48                         ans += 2;
49                     }
50                     else
51                         ++RR;
52                 }
53             }
54             arr[i] = node(LL, RR);
55         }
56         sort(arr + 1, arr + 1 + n);
57         int L = 0;
58         for (int i = 1; i <= n; ++i)
59         {
60             int LL = arr[i].l, RR = arr[i].r;
61             ans += min(L, RR) * 2;
62             L -= min(L, RR);
63             L += LL;
64         }
65         printf("%d\n", ans);
66     }
67     return 0;
68 }

C - Triangle Partition

水.(排序)

 1 #include<bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 const int maxn = 1e3 + 10;
 6
 7 struct node{
 8     int x, y, id;
 9     inline node(){}
10     inline node(int x, int y, int id):x(x), y(y), id(id){}
11     inline bool operator < (const node &b) const
12     {
13         return x == b.x ? y < b.y : x < b.x;
14     }
15 }P[maxn << 2];
16
17 int n;
18
19 int main()
20 {
21     int t;
22     scanf("%d", &t);
23     while(t--)
24     {
25         scanf("%d", &n);
26         for(int i = 1; i <= 3 * n; ++i)
27         {
28             scanf("%d %d", &P[i].x, &P[i].y);
29             P[i].id = i;
30         }
31         sort(P + 1, P + 1 + 3 * n);
32         for(int i = 1; i <= 3 * n; i += 3)
33         {
34             printf("%d %d %d\n", P[i].id, P[i + 1].id, P[i + 2].id);
35         }
36     }
37     return 0;
38 }

D - Distinct Values

按题意模拟即可。

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 #define N 100010
 6
 7 struct node
 8 {
 9     int l, r;
10     inline void scan()
11     {
12         scanf("%d%d", &l, &r);
13     }
14     inline bool operator < (const node &r) const
15     {
16         return l < r.l || (l == r.l && this->r > r.r);
17     }
18 }Data[N];
19
20 int t, n, m;
21 int ans[N];
22 bool vis[N];
23 int R;
24
25 int main()
26 {
27     scanf("%d", &t);
28     while (t--)
29     {
30         memset(ans, 0, sizeof ans);
31         R = 0;
32         scanf("%d%d", &n, &m);
33         for (int i = 1; i <= m; ++i) Data[i].scan();
34         sort(Data + 1, Data + 1 + m);
35         for (int i = 1; i <= m; ++i)
36         {
37             int l = Data[i].l, r = Data[i].r;
38             if (R >= r) continue;
39             if (R + 1 < l)
40                 for (int j = R + 1; j < l; ++j) ans[j] = 1;
41             memset(vis, false, sizeof vis);
42             for (int j = l; j <= R; ++j) vis[ans[j]] = true;
43             int L = 1;
44             for (int j = max(R + 1, l); j <= r; ++j)
45             {
46                 while (vis[L]) ++L;
47                 ans[j] = L;
48                 vis[L] = true;
49             }
50             R = max(R, r);
51         }
52         while (R < n)
53         {
54             R++;
55             ans[R] = 1;
56         }
57         for (int i = 1; i <= n; ++i) printf("%d%c", ans[i], " \n"[i == n]);
58     }
59     return 0;
60 }

E - Maximum Weighted Matching

留坑。

F - Period Sequence

留坑。

G - Chiaki Sequence Revisited

题意:定义$a_n$ 求 $\sum_{i = 1} ^ {i = n} a_i$

思路:先不考虑$a_1$

我们对每个最后一个2的幂次数处理出它前面有多少个数, 以及这些数的前缀和是多少

比如说处理出

1 2 4 8 16

1 3 7 15 31

1 5 20 76 288

然后给出n计算的时候 按二进制拆分 比如说

27 = 15 + 7 + 3 + 3

定义$F[i] 为 前面i个数的前缀和$

$ans[27] = F[15] + F[7] + 7 * 8 + F[3] + 3 * (8 + 2) + F[3] + 3 * (8 + 2 + 2)$

对于后面,相当于所有数向右偏移

注意取模

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 #define N 64
 6 #define ll long long
 7
 8 const ll MOD = (ll)1e9 + 7;
 9
10 int t;
11 ll n;
12 ll a[N], b[N], c[N];
13
14 inline void Init()
15 {
16     a[0] = 1;
17     for (int i = 1; i <= 59; ++i) a[i] = a[i - 1] << 1;
18     b[0] = 1;
19     for (int i = 1; i <= 59; ++i) b[i] = (b[i - 1] << 1) + 1;
20     c[0] = 1;
21     for (int i = 1; i <= 59; ++i) c[i] = ((c[i - 1] << 1) % MOD + (a[i - 1] % MOD) * (b[i - 1] % MOD) % MOD + a[i]) %MOD;
22 //    for (int i = 0; i <= 59; ++i) printf("%lld %lld %lld\n", a[i], b[i], c[i]);
23 }
24
25 int main()
26 {
27     Init(); scanf("%d", &t);
28     while (t--)
29     {
30         scanf("%lld", &n); --n;
31         ll ans = 1, tmp = 0;
32         for (int i = 59; i >= 0; --i)
33         {
34             while (n >= b[i])
35             {
36                 ans = (ans + c[i]) % MOD;
37                 ans = (ans + (b[i] % MOD * tmp) % MOD) % MOD;
38                 tmp = (tmp + a[i]) % MOD;
39                 n -= b[i];
40             }
41         }
42         printf("%lld\n", ans);
43     }
44     return 0;
45 }

H - RMQ Similar Sequence

留坑。

I - Lyndon Substring

留坑。

J - Turn Off The Light

留坑。

K - Time Zone

按题意模拟即可

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 int t, a, b;
 6 char s[10];
 7
 8 inline void work1()
 9 {
10     int ans = 0; int flag = 1;
11     if (s[0] == ‘-‘)
12         flag = -1;
13     int len = strlen(s);
14     for (int i = 1; i < len; ++i)
15         ans = ans * 10 + s[i] - ‘0‘;
16     ans *= flag;
17     int gap = ans - 8;
18     a = (a + gap + 24) % 24;
19     printf("%02d:%02d\n", a, b);
20     return;
21 }
22
23 inline void work2()
24 {
25     int A = 0, B = 0; int flag = 1;
26     if (s[0] == ‘-‘)
27         flag = -1;
28     int len = strlen(s), i;
29     for (i = 1; s[i] != ‘.‘; ++i)
30         A = A * 10 + s[i] - ‘0‘;
31     for (++i; i < len; ++i)
32         B = B * 10 + s[i] - ‘0‘;
33     int tot = a * 60 + b;
34     A *= flag, B = B * 6 * flag;
35     int tmptot = A * 60 + B - 480;
36     tot = (tot + tmptot + 24 * 60) % (24 * 60);
37     printf("%02d:%02d\n", tot / 60, tot % 60);
38     return;
39 }
40
41 int main()
42 {
43     scanf("%d", &t);
44     while (t--)
45     {
46         scanf("%d %d UTC%s", &a, &b, s);
47         bool flag = true;
48         for (int i = 0, len = strlen(s); i < len; ++i)
49             if (s[i] == ‘.‘)
50             {
51                 flag = false;
52                 break;
53             }
54         if (flag) work1();
55         else work2();
56     }
57     return 0;
58 }

原文地址:https://www.cnblogs.com/Dup4/p/9555094.html

时间: 2024-10-09 15:11:54

2018 Multi-University Training Contest 1 Solution的相关文章

2018 Multi-University Training Contest 4 Solution

A - Problem A. Integers Exhibition 留坑. B - Problem B. Harvest of Apples 题意:计算$\sum_{i = 0}^{i = m}C(n, i)$ 思路:由$sum_{i = 0}^{i = m}C(n,i)$可以得到$sum_{i = 0}^{i = m + 1}C(n,i)$以及$sum_{i = 0}^{i = m}C(n + 1,i)$然后用莫对算法求解 1 #include<bits/stdc++.h> 2 3 usi

2018 Multi-University Training Contest 6 Solution

A - oval-and-rectangle 题意:给出一个椭圆的a 和 b,在$[0, b]中随机选择c$ 使得四个顶点在椭圆上构成一个矩形,求矩形周长期望 思路:求出每种矩形的周长,除以b(积分) 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const double PI = acos(-1.0); 6 7 double a, b; 8 9 void RUN() 10 { 11 int t; 12 scanf("%

2018 Multi-University Training Contest 9 Solution

A - Rikka with Nash Equilibrium 题意:构造一个$n * m$的矩阵,使得$[1, n * m]$ 中每个数只出现一次,并且纳什均衡只出现一次. 思路:从大到小的放置,每一个都可以拓展一行拓展一列或者放在已经拓展的行列焦点,用记忆化搜索/dp即可 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 typedef long long ll; 6 7 int n, m; 8 ll p; 9 ll dp[81]

2018 Nowcoder Multi-University Training Contest 2

Practice Link A. run 题意: 白云每次可以移动\(1\)米或者\(k\)米,询问移动的米数在\([L, R]\)范围内的方案数有多少. 思路: \(dp[i][2]\)表示到第\(i\)米,是通过\(1\)米的方式过来的还是\(k\)米的方式过来的,递推即可. 代码: #include <bits/stdc++.h> using namespace std; #define N 100010 const int p = 1e9 + 7; int f[N][2], g[N];

2018 Nowcoder Multi-University Training Contest 1

Practice Link J. Different Integers 题意: 给出\(n\)个数,每次询问\((l_i, r_i)\),表示\(a_1, \cdots, a_i, a_j, \cdots, a_n\)中有多少个不同的数. 思路: 先分别离线求出\(a_1, \cdots a_i\)以及\(a_j, \cdots, a_n\)中有多少个不同的数. 再考虑有多少个数既在\([1, i]\)中也在\([j, n]\)中,再离线做一次. 考虑一个数第一次出现的时候,那么这个数下一次出现

2018 Nowcoder Multi-University Training Contest 5

Practice Link A. gpa 题意: 有\(n\)门课程,每门课程的学分为\(s_i\),绩点为\(c_i\),要求最多删除\(k\)门课程,使得gpa最高. gpa计算方式如下: \[ \begin{eqnarray*} gpa = \frac{\sum s_ic_i}{\sum s_i} \end{eqnarray*} \] 思路: 首先删去的课程越多,gpa肯定不会变得更差. 所以我们肯定是删去\(k\)门课程. 考虑二分答案,check的时候要满足: \[ \begin{eq

2018 Multi-University Training Contest 3

2018 Multi-University Training Contest 2 题解 A - Problem A. Ascending Rating 题目描述:给定一个序列,分别求出所有长度为\(m\)的区间的\(maxrating, count\),对于每个长度为\(m\)的区间,一开始\(maxrating=-1, count=0\),然后从左往右扫,扫到一个大于\(maxrating\)的值时,\(count+1, maxrating=\)那个数. solution 从左往右做,用单调队

HDU 2018 Multi-University Training Contest 3 Problem A. Ascending Rating 【单调队列优化】

任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6319 Problem A. Ascending Rating Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 5943    Accepted Submission(s): 2004 Problem Description Before

杭电2018多校第一场(2018 Multi-University Training Contest 1) 1001.Maximum Multiple (HDU6298)-数学思维题(脑子是个好东西,可惜我没有)

暑假杭电多校第一场,这一场是贪心场,很多贪心的题目,但是自己太菜,姿势挫死了,把自己都写吐了... 2018 Multi-University Training Contest 1 HDU6298.Maximum Multiple 题目意思就是给你一个n,找出来三个数x,y,z, 使得n=x+y+z,而且x,y,z都是n的因数,并且x*y*z为最大值,让你输出来x*y*z的最大值.如果没有满足条件的情况就输出-1. 由1=1/2+1/3+1/6=1/3+1/3+1/3=1/2+1/4+1/4,所