Problem A:折纸
为了好做一点,直接钦定往左折,折完如果非法就调整一下(
可以开一个坐标数组记录每个点折叠后的坐标zzz 60pts
然后发现边界只有可能是处理过的点,就不用每个点都记了,只记处理过的点就行了,100pts
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 3 int m; 4 long long n; 5 long long sega[3005]; 6 7 signed main() { 8 scanf("%lld%d", &n, &m); 9 long long l = 0, r = n; 10 for (int i = 1; i <= m; i++) { 11 scanf("%lld", &sega[i]); 12 for (int j = 1; j <= i - 1; j++) { 13 if (sega[j] < sega[i]) 14 sega[i] = 2 * sega[j] - sega[i]; 15 } 16 l = std::min(l, 2 * sega[i] - r), r = sega[i]; 17 if (l > r) std::swap(l, r); 18 } 19 printf("%lld ", r - l); 20 return 0; 21 }
Problem B:不等式
当没有%M我们裆燃会做啦
$L le Sx le R$ 用L求个x,判断Sx是否小于R。
当拓展到%M,我们改写一下:$L le Sx - My le R$.
移项乱搞后:$-R mod S le My le -L mod S$
可以继续递归下去(
再把边界搞一下就vans了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define bu_kai_long return 3 #define long_jian_zu_zong 0 4 5 int T; 6 long long m, s, l, r; 7 8 long long solve(long long m, long long s, long long l, long long r) { 9 if (l >= m || l > r) return -1; 10 if (l == 0) return 0; 11 s %= m; 12 if (s == 0) return -1; 13 long long ans = (l - 1) / s + 1; 14 if (ans * s <= r && ans * s < m) return ans; 15 long long L = (-r % s + s) % s, R = (-l % s + s) % s; 16 long long misaka = solve(s, m, L, R); 17 if (misaka == -1) return -1; 18 long long mikoto = (l + m * misaka - 1) / s + 1; 19 if (s * mikoto - m * misaka <= r) return mikoto; 20 return -1; 21 } 22 23 signed main() { 24 scanf("%d", &T); 25 while (T--) { 26 scanf("%lld%lld%lld%lld", &m, &s, &l, &r); 27 if (r >= m) r = m - 1; 28 printf("%lld ", solve(m, s, l, r)); 29 } 30 bu_kai_long long_jian_zu_zong; 31 }
Problem C:reverse
是我写不出来的数位DP:)
考场40分性价比还是很高的(
正解:设f[i][j][op1][op2]表示前i位,当前后缀长度为j,前缀reverse后与L比较的结果和比R比较的结果
这没啥说的,记搜就vans了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define ull unsigned long long 3 4 int T, a, b; 5 ull l, r; 6 7 namespace subtask1 { 8 void QAQ() { 9 printf("%llu ", r); 10 } 11 } 12 13 namespace subtask3 { 14 int A[23], B[23], C[23]; 15 ull f[23][23][4][4]; 16 bool vis[23][23][4][4]; 17 18 int cmp(int x, int y, int las) { 19 if (x < y) return 0; 20 else if (x == y) return las; 21 else return 2; 22 } 23 24 ull dfs(int pos, bool lim, int len, int op1, int op2) { 25 if (!pos) { 26 if (len < A[0]) op1 = 0; 27 if (len < B[0]) op2 = 0; 28 return (op1 && op2 != 2) ? 1 : 0; 29 } 30 if (!lim && vis[pos][len][op1][op2]) return f[pos][len][op1][op2]; 31 int upp = lim ? C[pos] : 9; 32 ull ans = 0; 33 for (int i = 0; i <= upp; i++) { 34 ans += dfs(pos - 1, lim && i == upp, 35 len + 1, cmp(i, A[len + 1], op1), cmp(i, B[len + 1], op2)); 36 } 37 if (!lim) { 38 vis[pos][len][op1][op2] = 1; 39 f[pos][len][op1][op2] = ans; 40 } 41 return ans; 42 } 43 44 void seprate(ull x, int dig[]) { 45 dig[0] = 0; 46 while (x) 47 dig[++dig[0]] = x % 10, x /= 10; 48 } 49 50 ull yukari() { 51 memset(vis, 0, sizeof(vis)); 52 memset(f, 0, sizeof(f)); 53 ull ret = 0; 54 for (int i = 1; i <= C[0]; i++) { 55 int upp = i == C[0] ? C[C[0]] : 9; 56 for (int j = 1; j <= upp; j++) { 57 ret += dfs(i - 1, j == upp && i == C[0], 58 1, cmp(j, A[1], 1), cmp(j, B[1], 1)); 59 } 60 } 61 return ret; 62 } 63 64 void QAQ() { 65 memset(A, 0, sizeof(A)); 66 memset(B, 0, sizeof(B)); 67 memset(C, 0, sizeof(C)); 68 seprate(l, A), seprate(r, B), seprate(r, C); 69 ull ans = yukari(); 70 memset(C, 0, sizeof(C)); 71 seprate(l - 1, C); 72 ans -= yukari(); 73 printf("%llu ", ans); 74 } 75 } 76 77 signed main() { 78 scanf("%d%d%d", &T, &a, &b); 79 while (T--) { 80 scanf("%llu%llu", &l, &r); 81 if (a && b) subtask1::QAQ(); 82 else subtask3::QAQ(); 83 } 84 return 0; 85 }