Codeforces Round #653 (Div. 3)(A, B, C, D, E1详解)
Codeforces Round #653 (Div. 3)
Required Remainder
Thinking(binary search)
既然是找最大值問題,我又懶得去推式子,于是我直接就上了一個二分,二分寫法比結論稍微繁瑣了一點吧,但是還是挺好想的。
根據題意,我們的任務就是找到一個最大的數,滿足ans=k?x+y<=nans = k * x + y <= nans=k?x+y<=n,于是我們就可以通過二分枚舉kkk,來得到我們的答案。通過題目給定的x,y,zx, y, zx,y,z的范圍,我們可以確定二分的區間最多不過0190 ~ 1^90?19。
Coding
#include <bits/stdc++.h> #define mp make_pair #define pb push_backusing namespace std;typedef long long ll; typedef pair<int, int> pii; typedef unsigned long long ull;const int inf = 0x3f3f3f3f; const double pi = acos(-1.0); const double eps = 1e-7;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (48 ^ c);c = getchar();}return f * x; }const int N = 1e6 + 10;char str[N];int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int _ = read();while(_--) {ll x = read(), y = read(), n = read();ll l = 0, r = 1e9 + 10;while(l < r) {ll mid = l + r + 1 >> 1;if(mid * x + y <= n) l = mid;else r = mid - 1;}printf("%lld\n", l * x + y);}return 0; }Multiply by 2, divide by 6
Thinking
判斷能否通過0個或者多個乘二的操作,使數字變成6的倍數。我們想想6的兩個質因子2,32, 32,3,要想達到這個目的,對于初始的nnn,只可能有這兩種質因子,否則我們一定達不到我們的目標。于是我們可以先對nnn,進行2,32, 32,3的質因數提取,假設得到的222的因子個數是num2num2num2, 333的因子個數是num3num3num3,因為我們是同時消去2,32, 32,3因子的,并且只能增加或者不增加222的因子個數,所以只有當num2<=num3num2 <= num3num2<=num3時,才能保證我們可以消去所有的2,32, 32,3因子,最后變成111。
Coding
#include <bits/stdc++.h> #define mp make_pair #define pb push_backusing namespace std;typedef long long ll; typedef pair<int, int> pii; typedef unsigned long long ull;const int inf = 0x3f3f3f3f; const double pi = acos(-1.0); const double eps = 1e-7;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (48 ^ c);c = getchar();}return f * x; }const int N = 1e6 + 10;char str[N];int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int _ = read();while(_--) {ll n = read();int num2 = 0, num3 = 0;while(n % 3 == 0) {n /= 3;num3++;}while(n % 2 == 0) {n /= 2;num2++;}//最后n不是1說明還存在其他的質因子。if(n != 1 || num2 > num3) puts("-1");else printf("%d\n", num3 + num3 - num2);}return 0; }Move Brackets
Thinking(Stack)
我們先找到所有的符合匹配的括號,最后就只剩下一種非法的括號了,以這種形式存在)() ()(形成)))))((((()))))((((()))))(((((這樣的排列,所以我們只需要將其后面的移到前面去,或者前面的移到后面去,任選一種進行操作,因此我們的花費將會是最后無法匹配的括號的對數,也就是棧中的元素的一半。
Coding
#include <bits/stdc++.h> #define mp make_pair #define pb push_backusing namespace std;typedef long long ll; typedef pair<int, int> pii; typedef unsigned long long ull;const int inf = 0x3f3f3f3f; const double pi = acos(-1.0); const double eps = 1e-7;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (48 ^ c);c = getchar();}return f * x; }const int N = 1e6 + 10;char str[N];int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int _; cin >> _;while(_--) {int n; cin >> n;stack<char> stk;for(int i = 1; i <= n; i++) {char temp; cin >> temp;if(stk.empty() || stk.top() == temp || temp == '(') stk.push(temp);else stk.pop();}printf("%d\n", stk.size() / 2);}return 0; }Zero Remainder Array
Thinking
對于給定的序列,我們需要的就是x(modk)=(1,2……k?2,k?1)x \pmod k = (1, 2 …… k - 2, k - 1)x(modk)=(1,2……k?2,k?1),這樣的數,才能使我們的序列變成都是kkk的倍數,假定k=4k = 4k=4,數組中存在兩個數分別為3,73, 73,7, 他們有一個共同點3(modk)=7(modk)3 \pmod k \ = 7 \pmod k3(modk)?=7(modk),也就是說我們在x(modk)x \pmod kx(modk)從0?>k?10 -> k - 10?>k?1,的一趟循環中,最多只能使其中的一個數變成ai(modk)=0a_i \pmod k = 0ai?(modk)=0,想必看到這里應該就搞懂了這道題了,我們就是要找到ai(modk)a_i \pmod kai?(modk)后出現的次數最多的非零數,當有多個出現次數相同的數時我們取ai(modk)a_i \pmod kai?(modk)的最小值,因為那個最小值一定是當xxx足夠大的時候才會滿足條件。
Coding
#include <bits/stdc++.h> #define mp make_pair #define pb push_backusing namespace std;typedef long long ll; typedef pair<int, int> pii; typedef unsigned long long ull;const int inf = 0x3f3f3f3f; const double pi = acos(-1.0); const double eps = 1e-7;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (48 ^ c);c = getchar();}return f * x; }const int N = 2e5 + 10;int a[N];int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int _ = read();while(_--) {int n = read(), k = read();for(int i = 1; i <= n; i++) {a[i] = read();a[i] %= k;}sort(a + 1, a + 1 + n, greater<int> ());int now_num = 1, ansn = a[1], num = 1;for(int i = 2; i <= n && a[i] != 0; i++) {if(a[i] == a[i - 1]) now_num++;else now_num = 1;if(now_num >= num) ansn = a[i], num = now_num;}if(ansn == 0){puts("0");continue;}// cout << num << " " << ansn << endl;printf("%lld\n", 1ll * k * (num - 1) + k - ansn + 1);}return 0; }Reading Books (easy version)
Thinking(Sort, greedy)
題意這里就不說明了,對于給定的條件,我們要同時滿足AliceandBobAlice and BobAliceandBob都要讀至少kkk本書,所以我們可以指定一個策略,不管這本書是AliceorBobAlice or BobAliceorBob喜歡,還是他們兩同時喜歡,我們都同時增加AliceandBobAlice and BobAliceandBob的當前的書的數量,因此在之前我們就需要對書本分類AliceAliceAlice喜歡的數組a,BobBobBob喜歡的數組b,兩個人都喜歡的數組c。接下來就時對這三個數組分別按照元素大小從小到大進行排序
當我們當前枚舉的ai+bj<=cka_i + b_j <= c_kai?+bj?<=ck?時我們顯然貪心的選擇ai,bja_i, b_jai?,bj?這兩本書,所以我們的總花費將會變成ans+=ai+bjans += a_i + b_jans+=ai?+bj?,否則的話我們將會選擇ckc_kck?,花費將變成ans+=ckans += c_kans+=ck?。
當我們第一個點枚舉完了后,大致存在三種情況aaa不可選,bbb不可選,ccc不可選。
所以接下來的枚舉我們必須分類討論了當a∣∣ba || ba∣∣b,不可選的時候,我們要達到條件只能通過選擇ccc來進行。否則的話我們就只能選擇a,ba, ba,b兩個組合選取了。
Code
#include <bits/stdc++.h> #define mp make_pair // #define pb push_backusing namespace std;typedef long long ll; typedef pair<int, int> pii; typedef unsigned long long ull;const int inf = 0x3f3f3f3f; const double pi = acos(-1.0); const double eps = 1e-7;inline ll read() {ll f = 1, x = 0;char c = getchar();while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9') {x = (x << 1) + (x << 3) + (48 ^ c);c = getchar();}return f * x; }const int N = 2e5 + 10;struct Node {int value, fa, fb;void input() {value = read(), fa = read(), fb = read();}void out() {printf("%d %d %d\n", value, fa, fb);}bool operator < (const Node & t) const {return value < t.value;} }a[N], b[N], c[N], in; //結構體就是數組的用處,不用管。是我自己一開始思路想的有點復雜,然后就寫了這么一個結構體。int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int n = read(), k = read(), na = 0, nb = 0, nc = 0;for(int i = 1; i <= n; i++) {in.input();if(in.fa && in.fb) c[++nc] = in;else if(in.fa) a[++na] = in;else if(in.fb) b[++nb] = in;//一定要注意特判 0 0的情況。}// cout << na << " " << nb << " " << nc << endl;sort(a + 1, a + 1 + na);sort(b + 1, b + 1 + nb);sort(c + 1, c + 1 + nc);int pa = 1, pb = 1, pc = 1, flag = 0;int numa = 0, numb = 0;ll ans = 0;while(pa <= na && pb <= nb && pc <= nc) {if(a[pa].value + b[pb].value <= c[pc].value) {ans += a[pa].value + b[pb].value;pa++, pb++;}else {ans += c[pc].value;pc++;}numa++, numb++;if(numa >= k && numb >= k) {flag = 1;break;}}// cout << ans << " " << numa << " " << numb << endl;if(flag) {printf("%lld\n", ans);return 0;}if(pa > na || pb > nb) {while(pc <= nc) {ans += c[pc].value;pc++;numa++, numb++;if(numa >= k && numb >= k) {flag = 1;break;}}}else {while(pa <= na && pb <= nb) {ans += a[pa].value + b[pb].value;pa++, pb++;numa++, numb++;if(numa >= k && numb >= k) {flag = 1;break;}}}if(flag) {printf("%lld\n", ans);return 0;}puts("-1");return 0; }總結
以上是生活随笔為你收集整理的Codeforces Round #653 (Div. 3)(A, B, C, D, E1详解)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中胚细胞美容功效与作用是什么
- 下一篇: 番泻叶的功效与减肥作用