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 ", 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 ", 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 ", 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 ", 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], " "[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 ", 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 ", s); 53 } 54 else 55 { 56 printf("IMPOSSIBLE "); 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 ", ans); 18 } 19 return 0; 20 }