【无码专区5】01串(大讨论+构造)
因為只有std,沒有自我實現,所以是無碼專區
主要是為了訓練思維能力
solution才是dls正解,但是因為只有潦草幾句,所以大部分會有我自己基于正解上面的算法實現過程,可能選擇的算法跟std中dls的實現不太一樣。
std可能也會帶有博主自己的注釋。
problem
多組數據,給定 n,mn,mn,m,構造一個 n+mn+mn+m 長度的 01 串。
- 包含 nnn 個 111,mmm 個 000。
- 將這個串看成二進制數后能被 333 整除。
- 沒有前導零,即高位第一位必須為 111。
分別輸出字典序最大和最小的符合條件的 01 串。不存在就輸出 -1。
T≤100,n,m≤1e5T\le 100,n,m\le 1e5T≤100,n,m≤1e5
我的想法
observation:二進制相鄰兩位若都是 111,則這兩個位代表的 222 的冪的和一定是 333 的倍數。
證明:2i+2i?1=(2+1)?2i?1=3k2^i+2^{i-1}=(2+1)·2^{i-1}=3k2i+2i?1=(2+1)?2i?1=3k。
如果 nnn 為偶數。
-
字典序最大一定是形如 1111...100...000 。
-
字典序最小第一時間肯定會以為是 00...011..11 ,但是要求不能出現前導零。所以第一位固定為 111 后,其代表的冪次,2i2^i2i 取模 333 一定是 1/21/21/2。
- 如果取模是 111,那么只需要某一位也為 111【2k≡2(mod3)2^k\equiv 2\pmod 32k≡2(mod3)】就又可以湊成倍數。形如 100...0010...0111..1111。
- 如果取模是 222,那么只需要第一位也為 111就湊成倍數,形如 100..0011..111。
如果 nnn 為奇數。
-
字典序最大。
肯定也是前面一堆連續的 111,然后最后面的 333 個數的冪次都是取模為 111。
形如 111..10..01..0100...00(最前面的連續 111 段長度肯定也是奇數)。
-
字典序最小。
首位是 111 沒得跑。肯定也是后面一堆連續的 111,然后最前面的 333 個數的冪次都是取模為 111。
形如 10...00010...010...011111...11(最后面的連續 111 段長度得是奇數)。
顯然,偶數一定是有解的。奇數就不一定了,因為可能 111 個數不夠。
solution
簡單的討論。
如果只有一個 111, 或者 111 的個數為奇數, 但 000 的個數不超過 111, 那么無解。
- 只有一個 111, 顯然無解。
- 如果 111 的個數為奇數, 000 的個數是 000 個, 那么一定是 1111...111 這樣, 無解。
- 如果 111 的個數為奇數, 000 的個數是 111 個, 那么相當于 1111...1111 減去一個 111, 但是 1111...11111111...11111111...1111 模三余 000, 減去一個 111 之后模三不等于 000,所以無解。
如果 nnn 是偶數, 那么最大值一定是 1111000000 這樣, 最小值首先放一個 111, 最后放 n?2n-2n?2 個 111,剩下的一個 111 用來和 第一個 111 之間放偶數個 000 保證能被 333 整除。
如果 nnn 是奇數,那么首先放 n?3n-3n?3 個 111,這部分能被 333 整除,然后放 10101,然后放若干個 000。最小值同理,開頭放一個 111,末尾放 n?3n-3n?3 個 111,中間放 101,保證 1 和 101 中間有奇數個 000,這樣前半部分也被整除了。
時間復雜度 O(n)O(n)O(n)。
std
#include <bits/stdc++.h> using namespace std;string mul(string a, int b) {string c;for (int i = 0; i < b; i++)c += a;return c; } string mx, mn;int main() {freopen("binary.in", "r", stdin);freopen("binary.out", "w", stdout);int T;scanf("%d", &T);while (T--) {int n, m;scanf("%d%d", &n, &m);if (n <= 1 || (n % 2 == 1 && m <= 1)) {mx = "-1";mn = "-1";} else {if (n % 2 == 0)mx = mul("1", n) + mul("0", m);elsemx = mul("1", n - 2) + "0101" + mul("0", m - 2);if (n % 2 == 0)mn = "1" + mul("0", m / 2 * 2) + "1" + mul("0", m % 2) + mul("1", n - 2);elsemn = "1" + mul("0", m / 2 * 2 - 1) + "101" + mul("0", m % 2) + mul("1", n - 3);}printf("%s\n%s\n", mx.c_str(), mn.c_str());} }總結
以上是生活随笔為你收集整理的【无码专区5】01串(大讨论+构造)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【网络流专练一】UVA五题(UVA121
- 下一篇: 智界 S7 搭载业界最薄 800V 高压