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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法马拉松24

發(fā)布時間:2023/12/13 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法马拉松24 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

算法馬拉松24

A?小C的多邊形

  • 題意:

n+1個點的多邊形。給外圈的邊標記上1~n,里圈的邊也標記上1~n,使得對于一個外圈相鄰點與中間點構成的三角形的邊權之和都相等。\(n \le 10^6\)

  • 題解:

顯然每個三角形權值和為\(\frac{3(n+1)}{2}\)

一開始簡化成n個數(shù)排一個環(huán),相鄰兩個數(shù)的和不相等并且有上下界,然后并不好做

構造了一下n=5發(fā)現(xiàn)外圈正好1..5,內(nèi)圈1,2之間填n

然后這樣寫一下交上就T了...不加輸出優(yōu)化tle 2333

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll;char c[20]; inline void put(int x) {int p = 0;while(x) c[++p] = x%10 + '0', x /= 10;while(p) putchar(c[p--]); } int n; void solve() {for(int i=1; i<=n; i++) put(i), putchar(' ');puts("");int sum = (n+1)/2*3-1, now = (n+3)/2-1;for(int i=1; i<=n; i++) {put(now); putchar(' ');now = sum - now;sum--;} } int main() { // freopen("in", "r", stdin);scanf("%d", &n); n--;if(~n&1) puts("0");else solve(); }


B?逆序對統(tǒng)計

  • 題意:

n個位置,\(1..m\)中每個數(shù)可以放在某一個位置,求逆序對最多個數(shù)。\(n \le 20, m \le 100\)

  • 題解:

比賽時幾乎想到正解了qwq

從小到大枚舉數(shù),然后放一個數(shù)只會與他位置后面的數(shù)構成逆序對,把n狀壓一下就行了

但當時認為如果位置i已經(jīng)有數(shù)了,還要減去位置i已經(jīng)構成的逆序對個數(shù),沒法維護

其實完全不用考慮有數(shù)的情況,加入再刪除和沒加入是一樣的,從沒數(shù)的狀態(tài)可以轉移呀

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; typedef long long ll; const int N = 105, M = (1<<20) + 5, INF = 1e9; inline int read(){char c=getchar(); int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f; }int n, m, a[N], all, one[M], f[2][M], cur; void print(int x) {for(int i=n-1; i>=0; i--) printf("%c", (x & (1<<i)) ? '1' : '0'); puts(""); } int main() {freopen("in", "r", stdin);n=read(); m=read();for(int i=1; i<=m; i++) a[i] = read() - 1;all = 1<<n;for(int i=0; i<=n; i++) one[1<<i] = 1;for(int i=1; i<all; i++) one[i] = one[i&-i] + one[i^(i&-i)];memset(f, -1, sizeof(f));f[cur][0] = 0;for(int i=0; i<m; i++, cur ^= 1) { int *g = f[cur], *d = f[cur^1];for(int s=0; s<all; s++) if(g[s] != -1) { //printf("f %d %d %d\n", i, s, g[s]); print(s);d[s] = max(d[s], g[s]);if(~ s & (1<<a[i+1])) {int ns = s | (1<<a[i+1]); d[ns] = max(d[ns], g[s] + one[ns >> (a[i+1] + 1)]);}g[s] = -1;}}printf("%d\n", f[cur][all-1]); }


C?俄羅斯方塊

  • 題意:

\(n * m \le 10^7\)的01網(wǎng)格,每次將一個俄羅斯方塊區(qū)域異或,問是否能全0.

  • 題解:

稍微玩一下發(fā)現(xiàn)可以做到:

  • 異或兩個相鄰格
  • 將一個1格任意移動
  • 這樣的話1的個數(shù)為奇數(shù)一定可行啊!

    然而我忽略了網(wǎng)格大小,至少要是2*3才行!

    這樣的話特判一下2*2 和1*x

    #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; typedef long long ll; const int N = 1e7+5; inline int read(){char c=getchar(); int x=0,f=1;while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}return x*f; }int n, m, a[N]; char s[N]; int main() {freopen("in", "r", stdin);int T = read();while(T--) {n = read(); m = read();if(n == 1 || m == 1) {if(n == 1) {scanf("%s", s+1); n = m; for(int i=1; i<=n; i++) a[i] = s[i] - '0';}else for(int i=1; i<=n; i++) a[i] = read();int flag = 1;for(int i=1; i<=n; i++) if(a[i]) {if(i+3 > n) {flag = 0; break;}for(int j=i; j<=i+3; j++) a[j] ^= 1;}puts(flag ? "Yes" : "No");continue;}int cnt = 0;for(int i=1; i<=n; i++) {scanf("%s", s+1);for(int j=1; j<=m; j++) cnt += (s[j] - '0') & 1;}if(n > m) swap(n, m);if(n >= 2 && m >= 3) puts((cnt & 1) ? "No" : "Yes");else if(n == 2 && m == 2) puts(cnt == 4 || cnt == 0 ? "Yes" : "No");} }


    D 單獨寫了 E F棄療

    轉載于:https://www.cnblogs.com/candy99/p/6793047.html

    總結

    以上是生活随笔為你收集整理的算法马拉松24的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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