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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

 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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

 

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 }
View Code

 

转载于:https://www.cnblogs.com/Dup4/p/9599425.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值