日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Educational Codeforces Round 113 (Rated for Div. 2) 个人题解 ABCD

發(fā)布時間:2023/12/20 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Educational Codeforces Round 113 (Rated for Div. 2) 个人题解 ABCD 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

A. Balanced Substring

題意
從給定的ababab串中找到任意一個a,ba,ba,b數(shù)量相等的子串并輸出。如果找不到輸出?1?1-1 -1?1?1.

分析

如果一個較大的子串符合要求,則其中必然出現(xiàn)"ababab“或者”bababa",故只找這兩種串即可。

另外n≤50n\leq 50n50,隨便你怎么暴力。

代碼

#include <bits/stdc++.h> #define fors(i, a, b) for(int i = (a); i <= (b); ++i) #define lson k<<1 #define rson k<<1|1 #define pb push_back #define lowbit(x) ((x)&(-(x))) #define mem(a) memset(a, 0, sizeof(a)) #define DDLC_ESCAPE_PLAN_FAILED ios::sync_with_stdio(false), cin.tie(0) #define int long long const int inf = 0x3f3f3f3f; const double dinf = 1e100; typedef long long ll; //const ll linf = 9223372036854775807LL; // const ll linf = 1e18; using namespace std;signed main() {DDLC_ESCAPE_PLAN_FAILED;int t;cin >> t;while(t--){int n;cin >> n;string s;cin >> s;bool flag = 0;for(int i = 0; i < s.size() - 1; ++i){if(s[i] != s[i + 1]){cout << i + 1 << ' ' << i + 2 << endl;flag = 1;break;}}if(!flag) cout << -1 << ' ' << -1 << endl;} }

B. Chess Tournament

題意

nnn個人兩兩比賽,他們分兩種人,第一種人不能夠有敗績,第二種人希望贏至少一局,存在平局。

問有沒有可能構(gòu)造出滿足所有人的最終結(jié)果,如果有,輸出任意一個結(jié)果。

分析

對于第一種人,他們不能有敗績,所以他們對局直接全部設(shè)為平局即可。

對于第二種人,他們要在內(nèi)部贏其他人至少一次。對于第 iii 個人,可以貪心地選取當(dāng)前剩余未比場次最多的人 jjj 來讓 iiijjj。也可以直接讓所有第二種人構(gòu)成一個環(huán),環(huán)上箭頭尾部贏,頭部輸,除環(huán)以外剩下的對局隨便填滿即可??傊?span id="ozvdkddzhkzd" class="katex--inline">n≤50n\leq 50n50,隨便怎么搞

代碼(貪心)

#include <bits/stdc++.h> #define fors(i, a, b) for(int i = (a); i <= (b); ++i) #define lson k<<1 #define rson k<<1|1 #define pb push_back #define lowbit(x) ((x)&(-(x))) #define mem(a) memset(a, 0, sizeof(a)) #define DDLC_ESCAPE_PLAN_FAILED ios::sync_with_stdio(false), cin.tie(0) // #define int long long const int inf = 0x3f3f3f3f; const double dinf = 1e100; typedef long long ll; //const ll linf = 9223372036854775807LL; // const ll linf = 1e18; using namespace std; struct node {int id, s, type; }a[55]; char m[55][55]; bool vis[55][55]; signed main() {// DDLC_ESCAPE_PLAN_FAILED;int t;cin >> t;while(t--){int n;cin >> n;mem(vis);fors(i, 1, n){a[i].id = i;scanf("%1d", &a[i].type);a[i].s = n; // 未比場數(shù)}vector<int> v;fors(i, 1, n){if(a[i].type == 2) v.pb(i);else{fors(j, 1, n){if(i == j) continue;m[i][j] = m[j][i] = '=';vis[i][j] = vis[j][i] = 1;a[j].s--, a[i].s--;}}}bool flag = 1;for(int i = 0; i < v.size(); ++i){int mx = 0, mxi;for(int j = 0; j < v.size(); ++j){if(i == j) continue;if(mx < a[v[j]].s && !vis[v[i]][v[j]]){mx = a[v[j]].s;mxi = v[j];}}if(mx == 0){flag = 0;break;}a[v[i]].s--, a[mxi].s--;m[v[i]][mxi] = '+', m[mxi][v[i]] = '-';vis[v[i]][mxi] = vis[mxi][v[i]] = 1;}fors(i, 1, n){fors(j, 1, n){if(!vis[i][j]){m[i][j] = '+', m[j][i] = '-';vis[i][j] = vis[j][i] = 1;}}}if(!flag) cout << "NO" << endl;else{cout << "YES" << endl;fors(i, 1, n){fors(j, 1, n){if(i == j){cout << 'X';continue;}cout << m[i][j];}cout << endl;}}}return 0; }

C. Jury Meeting

題意

nnn個數(shù),你需要把他們進(jìn)行排列,排列完后,從左至右,每個數(shù)依次減去1。當(dāng)一個數(shù)減為0后,它就會被跳過,不再減去。然后再從1開始,重復(fù)這個步驟,直到所有數(shù)都變成0。

你需要保證在這個過程中,不會有一個位置被連續(xù)減了兩次,求滿足條件的排列數(shù)。

分析

一個位置被連續(xù)減了兩次當(dāng)且僅當(dāng)除了它以外全都是0.

剩下的這個被連續(xù)減去的肯定也只可能是最大值了。

顯然可以知道:

  • 數(shù)列中所有數(shù)都相同時,全部排列都符合條件
  • 數(shù)列中最大值與次大值相差大于1,且最大值只有1個時,無論如何都不會滿足條件
  • 數(shù)列中最大值出現(xiàn)次數(shù)超過1時,全部排列都符合條件(和情況1相似)
  • 故我們只需要討論的情況只剩下:數(shù)列中最大值與次大值相差1,且最大值只出現(xiàn)一次的情況。

    要不使最大值被連續(xù)減去多次,當(dāng)且僅當(dāng)排列中最大值的后面存在次大值。

    例如3,3,43,3,43,3,4最后會被減成0,0,10,0,10,0,1,再減一次0,0,00,0,00,0,0,第三個位置就被連續(xù)減了兩次。但是3,4,33,4,33,4,3的話,最后減成0,1,00,1,00,1,0,最后減去第二個位置,但是第二個位置上一個減去的是第三個位置,不連續(xù)。

    所以我們找到一種排列,最大值的后面有次大值即可。

    為了稍微簡化計算,不妨考慮其互斥情況:最大值后面沒有次大值。

    那么我們利用高中排列組合的“插空法”。假設(shè)nnn個數(shù)中,有111個最大值,c2c2c2個次大值。從nnn個位置中選擇c2+1c2+1c2+1個位置,然后選出位置的最后一個放上最大值,其余位置用次大值進(jìn)行全排列,剩下的n?c2?1n-c2-1n?c2?1個位置再用其余數(shù)全排列,得到Cnc2+1?Ac2c2?An?c2?1n?c2?1C_{n}^{c2+1}·A_{c2}^{c2}·A_{n-c2-1}^{n-c2-1}Cnc2+1??Ac2c2??An?c2?1n?c2?1?,所以最終答案是
    ans=Ann?Cnc2+1?Ac2c2?An?c2?1n?c2?1ans= A_n^n - C_{n}^{c2+1}·A_{c2}^{c2}·A_{n-c2-1}^{n-c2-1} ans=Ann??Cnc2+1??Ac2c2??An?c2?1n?c2?1?
    (當(dāng)然,正向考慮并不比這個互斥情況復(fù)雜,直接ans=Cnc2+1?Cc21?Ac2c2?An?c2?1n?c2?1ans=C_n^{c2+1}·C_{c2}^1·A_{c2}^{c2}·A_{n-c2-1}^{n-c2-1}ans=Cnc2+1??Cc21??Ac2c2??An?c2?1n?c2?1?,昨晚有點多此一舉)

    具體實現(xiàn)上使用了Lucas定理,復(fù)雜度O(nlogn)O(nlogn)O(nlogn),注意最后做減法的時候取模。

    代碼

    #include <bits/stdc++.h> #define fors(i, a, b) for(int i = (a); i <= (b); ++i) #define lson k<<1 #define rson k<<1|1 #define pb push_back #define lowbit(x) ((x)&(-(x))) #define mem(a) memset(a, 0, sizeof(a)) #define DDLC_ESCAPE_PLAN_FAILED ios::sync_with_stdio(false), cin.tie(0) #define int long long const int inf = 0x3f3f3f3f; const double dinf = 1e100; typedef long long ll; //const ll linf = 9223372036854775807LL; // const ll linf = 1e18; using namespace std; const int maxn = 2e5 + 10; int pi[maxn]; const int mod = 998244353LL; int qpow(int a, int b) {int ans = 1;a %= mod;while(b){if(b & 1){ans = ans * a % mod;}b >>= 1;a = a * a % mod;}return ans; } int C(int n, int m) {if(m > n) return 0;int ans = 1;fors(i, 1, m){int a = (n + i - m) % mod;int b = i % mod;ans = ans * (a * qpow(b, mod - 2) % mod) % mod; }return ans % mod; } void prework() {pi[0] = 1;pi[1] = 1;fors(i, 1, maxn - 1){pi[i] = (pi[i - 1] * i) % mod;} } int a[maxn]; signed main() {DDLC_ESCAPE_PLAN_FAILED;int t;cin >> t;prework();while(t--){int n;cin >> n;fors(i, 1, n) cin >> a[i];int mx = 0;fors(i, 1, n) mx = max(mx, a[i]);int tmx = 0;fors(i, 1, n){if(a[i] > tmx && a[i] != mx) tmx = a[i];}int c1 = 0, c2 = 0;fors(i, 1, n){if(a[i] == mx) c1++;else if(a[i] == tmx) c2++;}if(c2 == 0 || c1 > 1){cout << pi[n] << endl;}else if(mx - tmx > 1){cout << 0 << endl;}else{int ans = C(n, c1 + c2);ans = (ans * pi[c1]) % mod;ans = (ans * pi[c2]) % mod;ans = (ans * pi[n - c1 -c2]) % mod;ans = pi[n] - ans;ans += 2 * mod;ans %= mod;cout << ans << endl;}}return 0; }

    D. Inconvenient Pairs

    題意

    在一個坐標(biāo)從(0,0)(0,0)(0,0)(1e6,1e6)(1e6,1e6)(1e6,1e6)的正方形框里,有nnn條橫直線,mmm條縱直線。輸入保證邊界也是直線之一?,F(xiàn)在有kkk個點分布在各個確定的直線上,只能通過已經(jīng)畫出的線移動,當(dāng)一對點之間的最短路大于他們之間的曼哈頓距離時,這對點稱為inconvenient,問有多少對inconvenient的點。

    分析

    當(dāng)一個點在橫線豎線的交點上時,它肯定不做貢獻(xiàn),到任意其他的點的最短路程都是曼哈頓距離。

    但當(dāng)兩個點同在橫線上但不是同一個橫線上時,就有可能做貢獻(xiàn)了。豎線同理。

    如果兩個點在橫線上,且不在同一橫線上,而且他們都被夾在相鄰的兩豎線之間,那么肯定就是inconvenient pair了,豎線同理。

    我們需要算出,任意兩相鄰豎線之間有多少條在橫線上的點,并排除掉在同一橫線上的情況,然后計算答案。

    具體就是用map存有哪些橫(縱)邊,然后對每個縱(橫)邊上的點用二分查找查出它在哪兩個橫(縱)邊之間,答案先加上目前已統(tǒng)計的這兩條橫邊之間的點的數(shù)目,再減去點所在縱邊上原來有的點的數(shù)目。

    代碼

    #include <bits/stdc++.h> #define fors(i, a, b) for(int i = (a); i <= (b); ++i) #define lson k<<1 #define rson k<<1|1 #define pb push_back #define lowbit(x) ((x)&(-(x))) #define mem(a) memset(a, 0, sizeof(a)) #define DDLC_ESCAPE_PLAN_FAILED ios::sync_with_stdio(false), cin.tie(0) #define int long long const int inf = 0x3f3f3f3f; const double dinf = 1e100; typedef long long ll; //const ll linf = 9223372036854775807LL; // const ll linf = 1e18; using namespace std; const int maxn = 2e5 + 10; int v[maxn], h[maxn]; signed main() {DDLC_ESCAPE_PLAN_FAILED;int t;cin >> t;while(t--){map<int, bool> verti, horiz;map<pair<int, int>, int> onY, onX;map<int, int> cntx, cnty;int n, m, k;cin >> n >> m >> k;fors(i ,1, n) cin >> v[i], verti[v[i]] = 0;fors(i, 1, m) cin >> h[i], horiz[h[i]] = 0;int x, y;int ans = 0;fors(i, 1, k){cin >> x >> y;if(verti.count(x) && horiz.count(y)) continue;else{int px = lower_bound(v + 1, v + 1 + n, x) - v;int py = lower_bound(h + 1, h + m + 1, y) - h;if(verti.count(x)){ans += cnty[py] - onX[{py, x}];cnty[py]++, onX[{py, x}]++;}else{ans += cntx[px] - onY[{px, y}];cntx[px]++, onY[{px, y}]++;}}}cout << ans << endl;}return 0; }

    總結(jié)

    以上是生活随笔為你收集整理的Educational Codeforces Round 113 (Rated for Div. 2) 个人题解 ABCD的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。