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 using namespace std;
 4
 5 typedef long long ll;
 6
 7 const ll MOD = 1e9 + 7;
 8 const int maxn = 1e5 + 10;
 9
10 int unit;
11 ll inv[maxn];
12 ll invfac[maxn];
13 ll fac[maxn];
14 ll ans[maxn];
15 int n, m;
16
17 struct node{
18     int l, r, id;
19     inline node(){}
20     inline node(int l, int r, int id) :l(l), r(r), id(id){}
21     inline bool operator < (const node &b) const
22     {
23         if(l / unit != b.l / unit)    return l / unit < b.l / unit;
24         else return r < b.r;
25     }
26 }arr[maxn];
27
28 inline void Init()
29 {
30     fac[0] = invfac[0] = 1;
31     fac[1] = inv[1] = invfac[1] = 1;
32     for(int i = 2; i < maxn; ++i)
33     {
34         fac[i] = fac[i - 1] * i % MOD;
35         inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD;
36         invfac[i] = invfac[i - 1] * inv[i] % MOD;
37     }
38 }
39
40 inline ll cal(int a, int b)
41 {
42     ll res = fac[a] * invfac[b] % MOD * invfac[a - b] % MOD;
43     return res;
44 }
45
46 inline void work()
47 {
48     ll tmp = 0;
49     for(int i = 0; i <= arr[1].r; ++i)
50     {
51         tmp = (tmp + cal(arr[1].l, i)) % MOD;
52     }
53     ans[arr[1].id] = tmp;
54     int L = arr[1].l, R = arr[1].r;
55     for(int i = 2; i <= n; ++i)
56     {
57         while(L < arr[i].l)
58         {
59             tmp = (tmp * 2 % MOD- cal(L++, R) + MOD) % MOD;
60         }
61         while(L > arr[i].l)
62         {
63             tmp = (tmp + cal(--L, R) + MOD) % MOD * inv[2] % MOD;
64         }
65         while(R < arr[i].r)
66         {
67             tmp = (tmp + cal(L, ++R)) % MOD;
68         }
69         while(R > arr[i].r)
70         {
71             tmp = (tmp - cal(L, R--) + MOD) % MOD;
72         }
73         ans[arr[i].id] = tmp;
74     }
75 }
76
77 int main()
78 {
79     Init();
80     scanf("%d", &n);
81     for(int i = 1; i <= n; ++i)
82     {
83         scanf("%d %d", &arr[i].l, &arr[i].r);
84         arr[i].id = i;
85     }
86     unit = (int)sqrt(n);
87     sort(arr + 1, arr + 1 + n);
88     work();
89     for(int i = 1; i <= n; ++i)
90     {
91         printf("%lld\n", ans[i]);
92     }
93     return 0;
94 }

C - Problem C. Problems on a Tree

留坑。

D - Problem D. Nothing is Impossible

题意:给出n道题目,每道题目有$a_i种正确选择,b_i种错误选择$ 一共有m个人,所有人都要选择一个题目集合去做,相当于去试答案,问最多能试出多少道题目答案

思路:排序,前缀积。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 #define N 110
 5 #define ll long long
 6
 7 struct node
 8 {
 9     int a, b, sum;
10     inline void scan()
11     {
12         scanf("%d%d", &a, &b);
13         sum = a + b;
14     }
15     inline bool operator < (const node &r) const
16     {
17         return sum < r.sum;
18     }
19 }arr[N];
20
21 int t, n, m;
22 ll sum;
23
24 int main()
25 {
26     scanf("%d", &t);
27     while (t--)
28     {
29         scanf("%d%d", &n, &m);
30         for (int i = 1; i <= n; ++i) arr[i].scan();
31         sort(arr + 1, arr + 1 + n);
32         int ans = 0; sum = 1;
33         for (int i = 1; i <= n; ++i)
34         {
35             sum *= arr[i].sum;
36             if (sum > m) break;
37             ans = i;
38         }
39         printf("%d\n", ans);
40     }
41     return 0;
42 }

E - Problem E. Matrix from Arrays

题意:给出一种构造二维数组的构造方式,然后给出一个左上角,一个右下角,求这个矩形内的数和

思路:打表找规律发现,大矩阵是由若干个$2L \cdot 2L$个小矩阵构成的,那么把给出的矩阵分成四块,整块整块的处理,边边角角的处理

 1 #include<bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 #define N 110
 6
 7 typedef long long ll;
 8
 9 int n;
10 int x[2], y[2];
11 ll arr[N];
12 ll G[N][N];
13
14 inline ll cal(int x,int y)
15 {
16     if(x < 0 || y < 0) return 0ll;
17     ll res = G[n - 1][n - 1] * (x / n) * (y / n) + G[n - 1][y % n] * (x / n) + G[x % n][n - 1] * (y / n) + G[x % n][y % n];
18     return res;
19 }
20
21 int main()
22 {
23     int t;
24     scanf("%d", &t);
25     while(t--)
26     {
27         scanf("%d", &n);
28         for(int i = 0; i < n; ++i)
29         {
30             scanf("%lld", arr + i);
31         }
32         for(int i = 0, cnt = 0; i < (n << 2); ++i)
33         {
34             for(int j = 0; j <= i; ++j)
35             {
36                 G[j][i - j] = arr[cnt];
37                 cnt = (cnt + 1) % n;
38             }
39         }
40         n <<= 1;
41         for(int i = 0; i < n; ++i)
42         {
43             for(int j = 0; j < n; ++j)
44             {
45                 G[i][j] += (i ? G[i - 1][j] : 0);
46                 G[i][j] += (j ? G[i][j - 1] : 0);
47                 G[i][j] -= ((i && j) ? G[i - 1][j - 1] : 0);
48             }
49         }
50         int q;
51         scanf("%d", &q);
52         while(q--)
53         {
54             scanf("%d %d %d %d", &x[0], &y[0], &x[1], &y[1]);
55             ll ans = cal(x[1], y[1]) - cal(x[0] - 1, y[1]) - cal(x[1], y[0] - 1) + cal(x[0] - 1, y[0] - 1);
56             printf("%lld\n", ans);
57         }
58     }
59     return 0;
60 }

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 #define N 1100
 5 #define ll long long
 6
 7 int t, n, q, x[2], y[2];
 8 ll arr[N];
 9 ll G[N][N];
10
11 int main()
12 {
13     scanf("%d", &t);
14     while (t--)
15     {
16         scanf("%d", &n);
17         for (int i = 1; i <= n; ++i) scanf("%lld", arr + i);
18         memset(G, 0, sizeof G);
19         for (int i = 0, cnt = 0; i <= (n << 2); ++i)
20         {
21             for (int j = 0; j <= i; ++j)
22             {
23                 G[j][i - j] = arr[cnt + 1];
24                 cnt = (cnt + 1) % n;
25             }
26         }
27         n <<= 1;
28         ll base = 0;
29         for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) base += G[i][j];
30         scanf("%d", &q);
31         while (q--)
32         {
33             scanf("%d%d%d%d", &x[0], &y[0], &x[1], &y[1]);
34             ll ans = 0, tmp;
35             //compute Big
36             ll xl = (x[1] - x[0] + 1) / n, yl = (y[1] - y[0] + 1) / n; ans += (base * xl * yl);
37             //compute lower_left corner
38             tmp = 0;
39             for (int i = x[0] + xl * n; i <= x[1]; ++i)
40             {
41                 for (int j = y[0], cnt = 1; cnt <= n; ++cnt, ++j)
42                     tmp += G[i % n][j % n];
43             }
44             //compute upper_right corner
45             ans += tmp * yl; tmp = 0;
46             for (int i = x[0], cnt = 1; cnt <= n; ++cnt, ++i)
47             {
48                 for (int j = y[0] + yl * n; j <= y[1]; ++j)
49                     tmp += G[i % n][j % n];
50             }
51             //compute lower_right corner
52             ans += tmp * xl; tmp = 0;
53             for (int i = x[0] + xl * n; i <= x[1]; ++i)
54             {
55                 for (int j = y[0] + yl * n; j <= y[1]; ++j)
56                     ans += G[i % n][j % n];
57             }
58             printf("%lld\n", ans);
59         }
60     }
61     return 0;
62 }

F - Problem F. Travel Through Time

留坑。

G - Problem G. Depth-First Search

留坑。

H - Problem H. Eat Cards, Have Fun

留坑。

I - Problem I. Delightful Formulas

留坑。

J - Problem J. Let Sudoku Rotate

题意:给出一个16 * 16 的数独, 有一些4 * 4 的矩阵被逆时针旋转过,然后求恢复最少需要旋转多少次

思路:爆搜,两条剪枝,一个是判断是否有冲突,一个是判断当前步数是否比已有答案大

  1 #include<bits/stdc++.h>
  2
  3 using namespace std;
  4
  5 const int maxn = 1e2 + 10;
  6
  7 int ans;
  8 bool vis[20];
  9 char s[20];
 10 int G[maxn][maxn];
 11
 12 inline bool judge(int x,int y)
 13 {
 14     for(int i = x * 4 - 3; i <= x * 4; ++i)
 15     {
 16         memset(vis, false, sizeof vis);
 17         for(int j = 1; j <= y * 4; ++j)
 18         {
 19             if(vis[G[i][j]]) return false;
 20             vis[G[i][j]] = true;
 21         }
 22     }
 23     for(int i = y * 4 - 3; i <= y * 4; ++i)
 24     {
 25         memset(vis, false, sizeof vis);
 26         for(int j = 1;  j <= x * 4; ++j)
 27         {
 28             if(vis[G[j][i]]) return false;
 29             vis[G[j][i]] = true;
 30         }
 31     }
 32     return true;
 33 }
 34
 35 inline void fun(int x, int y)
 36 {
 37     int tmp[10][10];
 38     for(int i = 1; i <= 4; ++i)
 39     {
 40         for(int j = 1; j <= 4; ++j)
 41         {
 42             tmp[j][4 - i + 1] = G[(x - 1) * 4 + i][(y - 1) * 4 + j];
 43         }
 44     }
 45     for(int i = 1; i <= 4; ++i)
 46     {
 47         for(int j = 1; j <= 4; ++j)
 48         {
 49             G[(x - 1) * 4 + i][(y - 1) * 4 + j] = tmp[i][j];
 50         }
 51     }
 52 }
 53 inline void DFS(int x,int y,int res)
 54 {
 55     if(res >= ans) return ;
 56     if(y > 4)
 57     {
 58         DFS(x + 1, 1, res);
 59         return ;
 60     }
 61     if(x == 5)
 62     {
 63         ans = min(ans, res);
 64         return ;
 65     }
 66     for(int i = 0; i < 4; ++i)
 67     {
 68         if(i)
 69         {
 70             fun(x, y);
 71 /*            if(x == 3 && y == 1 && i == 1)
 72             {
 73                 for(int i = x * 4 - 3; i <= x * 4; ++i)
 74                 {
 75                     for(int j = y * 4 - 3; j <= y * 4; ++j)
 76                     {
 77                         printf("%d%c", G[i][j], " \n"[j == y * 4]);
 78                     }
 79                 }
 80             }*/
 81         }
 82         if(judge(x, y))
 83         {
 84             DFS(x, y + 1, res + i);
 85         }
 86     }
 87     fun(x, y);
 88 }
 89
 90 int main()
 91 {
 92     int t;
 93     scanf("%d", &t);
 94     while(t--)
 95     {
 96         ans = 1 << 16;
 97         for(int i = 1; i <= 16; ++i)
 98         {
 99             scanf("%s", s + 1);
100             for(int j = 1; j <= 16; ++j)
101             {
102                 if(s[j] >= ‘0‘ && s[j] <= ‘9‘)
103                 {
104                     G[i][j] = s[j] - ‘0‘;
105                 }
106                 else if(s[j] >= ‘A‘ && s[j] <= ‘F‘)
107                 {
108                     G[i][j] = (s[j] - ‘A‘) + 10;
109                 }
110             }
111         }
112     //    fun(1, 1);
113         DFS(1, 1, 0);
114         printf("%d\n", ans);
115     }
116     return 0;
117 }

K - Problem K. Expression in Memories

按题意模拟即可

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

L - Problem L. Graph Theory Homework

水。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 #define N 100010
 5
 6 int t, n;
 7 int arr[N];
 8
 9 int main()
10 {
11     scanf("%d", &t);
12     while (t--)
13     {
14         scanf("%d", &n);
15         for (int i = 1; i <= n; ++i) scanf("%d", arr + i);
16         int ans = (int)floor(sqrt(abs(arr[1] - arr[n])));
17         printf("%d\n", ans);
18     }
19     return 0;
20 }

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

时间: 2024-10-30 15:49:11

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

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} =

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,所