BUC2 BUC3388A - 三五倍数答案 233168
思路 暴力。
代码
1 2 3 4 int ans = 0 ;for (int i = 1 ; i < 1000 ; ++i) if (!(i % 3 ) || !(i % 5 )) ans += i; printf ("%d\n" , ans);
BUC3388B - 回文乘积答案 906609
思路 无需技巧地暴力,答案秒出。
代码
1 2 3 4 5 int ans = 0 ;for (int i = 100 ; i < 1000 ; ++i) for (int j = 100 ; j < 1000 ; ++j) if (judge (i * j)) ans = max (ans, i * j); printf ("%d\n" , ans);
其中 judge()
函数:
1 2 3 4 5 bool judge (int n) { int s = n, y = 0 ; while (s > 0 ) y = y * 10 + s % 10 , s = s / 10 ; return y == n; }
BUC3388C - 整除正数答案 61465412
思路 统计每个数的每个素因子的幂次,每个素因子取最高的幂次,再相乘。
代码
1 2 3 4 5 6 7 8 9 10 11 for (int i = 2 ; i <= 2023 ; ++i) { memset (t, 0 , sizeof t); int n = i; for (int j = 2 ; j <= n; ++j) { while (!(n % j)) n /= j, ++t[j]; a[j] = max (a[j], t[j]); } } ll ans = 1 ; for (int i = 2 ; i <= 2023 ; ++i) ans = ans * qpow (i, a[i]) % MOD;printf ("%lld\n" , ans % MOD);
BUC3388D - Fibonacci思路 手算(?)然后直接输出即可。
代码
1 2 3 ll a[] = { 0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 , 55 , 89 , 144 , 233 , 377 , 610 , 987 , 1597 , 2584 , 4181 , 6765 , 10946 , 17711 , 28657 , 46368 , 75025 , 121393 , 196418 , 317811 , 514229 , 832040 , 1346269 , 2178309 , 3524578 , 5702887 , 9227465 , 14930352 , 24157817 , 39088169 , 63245986 , 102334155 , 165580141 , 267914296 , 433494437 , 701408733 , 1134903170 , 1836311903 , 2971215073 , 4807526976 }; int n; scanf ("%d" , &n);printf ("%lld\n" , a[n]);
BUC3388E - 字串加工1 2 3 4 5 6 7 8 9 bool is1 = 0 , is0 = 0 ;ll cnt = 0 ; scanf ("%s" , s);for (int i = 0 ; i < strlen (s); ++i) { if (s[i] == '1' ) is1 = 1 ; else is0 = 1 ; if (is1 && is0) ++cnt, is1 = is0 = 0 ; } printf ("%lld\n" , cnt);
BUC3388F - 有趣的制造思路 首先预处理找到所有喜欢的数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 int cnt = 0 ;void dfs (std::string a, int pos, int x) { if (pos == x) { std::cout << a << ", " ; ++cnt; return ; } dfs (a + "3" , pos + 1 , x); dfs (a + "7" , pos + 1 , x); } void eachT () { std::cout << "a[] = { 0, " ; for (int i = 1 ; i < 10 ; ++i) { dfs ("3" , 1 , i); dfs ("7" , 1 , i); std::cout << "3333333333 }" ; } }
然后得到这么一串结果 a[] = { 0, 3, 7, 33, 37, 73, 77, 333, 337, 373, 377, 733, 737, 773, 777, 3333, 3337,
……
又,计算f ( x ) f(x) f ( x ) 的前x x x 项:
1 2 3 4 5 6 7 ll solve (int x) { int p = std::lower_bound (a, a + 1023 , x) - a; ll ans = 0 ; for (int i = 1 ; i < p; ++i) ans += a[i] * (a[i] - a[i - 1 ]); ans += a[p] * (x - a[p - 1 ]); return ans; }
答案即是 solve(r) - solve(l - 1)
。
BUC3388G - 流吧!我的眼泪思路 二分。
代码 二分判断函数:
1 2 3 4 5 bool half (int x) { ll sum = 0 ; for (int i = 0 ; i < n; ++i) sum += (a[i] - 1 ) / x + 1 ; return sum > m; }
注意向上取整⌈ A B ⌉ \lceil\frac{A}{B}\rceil ⌈ B A ⌉ 用代码写为 (A-1)/B+1
。
BUC3388H - 再会,谢谢所有的鱼 - UPSOLVE思路 (初学DP,不知道这算不算) 先枚举第一个区间,用一个数组 b[]
存每一个点左边的连续k k k 项的和的最大值,再枚举第二个区间,每次枚举的连续k k k 项和加上预处理结果,取最大值即可。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 int n, k;scanf ("%d %d" , &n, &k);for (int i = 1 ; i <= n; ++i) { scanf ("%lld" , &a[i]); s[i] = s[i - 1 ] + a[i]; b[i] = -1e18 ; } ll ans = -1e18 ; for (int i = k; i <= n; ++i) b[i] = max (b[i - 1 ], s[i] - s[i - k]); for (int i = k; i <= n - k; ++i) ans = max (ans, b[i] + s[i + k] - s[i]); printf ("%lld\n" , ans);
BUC3388I - 木头加工思路 即求最大公约数。
代码
1 2 3 4 5 6 7 8 int n;ll x, ans; scanf ("%d%lld" , &n, &ans);while (--n) { scanf ("%lld" , &x); ans = gcd (ans, x); } printf ("%lld\n" , ans);
BUC3388J - 进阶 FibonacciF i r s t b l o o d 撒花! \color{magenta}\rm First blood \text{撒花!} F i r s t b l o o d 撒花!
思路 首先注意F i b o n a c c i \rm Fibonacci F i b o n a c c i 前n n n 项的平方和等于F n F n + 1 F_nF_{n+1} F n F n + 1 ,所以这本质还是求F i b o n a c c i \rm Fibonacci F i b o n a c c i 数列。数据很大,用数组存已经不现实了,公式法也会超时,而且不能取模。事实上,这是矩阵快速幂的典型例题,可参考 [洛谷P1962][https://www.luogu.com.cn/problem/P1962 ]。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 struct matrix { ll a1, a2, b1, b2; matrix (ll a1, ll a2, ll b1, ll b2) : a1 (a1), a2 (a2), b1 (b1), b2 (b2) {} matrix operator *(const matrix& y) { matrix ans ((a1 * y.a1 + a2 * y.b1) % MOD, (a1 * y.a2 + a2 * y.b2) % MOD, (b1 * y.a1 + b2 * y.b1) % MOD, (b1 * y.a2 + b2 * y.b2) % MOD) ; return ans; } }; matrix qpow (matrix a, ll n) { matrix ans (1 , 0 , 0 , 1 ) ; while (n) { if (n & 1 ) ans = ans * a; a = a * a; n >>= 1 ; } return ans; } void eachT () { ll x; matrix M (0 , 1 , 1 , 1 ) ; scanf ("%lld" , &x); matrix ans = qpow (M, x + 1 ); printf ("%lld\n" , (ans.a1 * ans.a2) % MOD); }
BUC3388K - 数轴世界郊游再次 F i r s t b l o o d 撒花! \color{magenta}\rm \text{再次} First blood \text{撒花!} 再次 F i r s t b l o o d 撒花!
思路 一个格子一个格子搜,贪心地搜,优先找只能在这个格子里的,再找活动范围小的。
实现 首先定义两个结构体,t[]
用来临时存每次询问的数据:
1 2 3 4 struct node { ll l, r; } a[maxN], t[maxN]; bool cmp(node a, node b) { return (a.l == b.l) ? (a.r < b.r) : (a.l < b.l); }
每次询问初始化结构体:memset(&t, 0, sizeof(struct node));
。
首先将在查询范围内的点存入 t[]
:
1 2 3 4 5 6 7 for (int i = 0 ; i < n; ++i) { if (a[i].l <= r && a[i].r >= l) { t[cnt].l = max (a[i].l, l); t[cnt].r = min (a[i].r, r); ++cnt; } }
然后一个个搜,具体过程见注释:
1 2 3 4 5 6 7 8 9 10 while (l <= r) { std::sort (t + pos, t + cnt, cmp); while (t[pos].r < l && pos < cnt) pos++; if (pos == cnt) break ; if (t[pos].l == l && t[pos].l <= t[pos].r) ++ans, ++pos; ++l; for (int i = pos; i < cnt; ++i) t[i].l = max (t[i].l, l); }
愉快输出 printf("%d\n", ans);
W A \mathbf{WA} W A 第五行 if (t[pos].l == l && t[pos].l <= t[pos].r)
写的是 if (t[pos].l >= l)
,某些不在这个格子活动的点也算进去了。
BUC3388L - 超级 FibonacciLink
BUC3388M - 数字显示屏仿真思路 把样例给的图案存起来*(用C写过游戏的应该熟悉这个过程,作者上次模拟UNO牌,就是这样画的)*
1 2 3 4 5 6 std::string s[5 ][10 ] = { {" - " ," " ," - " ," - " ," " ," - " ," - " ," - " ," - " ," - " }, {"| |" ," |" ," |" ," |" ,"| |" ,"| " ,"| " ," |" ,"| |" ,"| |" }, {" " ," " ," - " ," - " ," - " ," - " ," - " ," " ," - " ," - " }, {"| |" ," |" ,"| " ," |" ," |" ," |" ,"| |" ," |" ,"| |" ," |" }, {" - " ," " ," - " ," - " ," " ," - " ," - " ," " ," - " ," - " } };
然后按要求输出即可:
1 2 3 4 5 6 7 std::string a; std::cin >> a; for (int j = 0 ; j < 5 ; ++j) { for (int i = 0 ; i < a.size (); ++i) std::cout << s[j][a[i] - '0' ]; std::cout << std::endl; }
總結今天突然長腦子了!做起來炒雞順利,以平均五分鐘一題的速度A C \rm AC A C 了A B C D E J I \rm ABCDEJI A B C D E J I ,然後在K \rm K K 上耗了一個小時,先回去把G M \rm GM G M 秒了,又磨了一個小時寫K \rm K K ,搶到了一血,最後兩個題H L \rm HL H L ,看這兩個都不像是我會寫的亞子就睡了一覺、、、、醒來後寫L \rm L L ,做出來提交時顯示比賽結束、、、晚了10 10 1 0 分鐘,痛失o n l y A C \rm onlyAC o n l y A C 、、、、