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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Problem B: 故障电灯(light)

發布時間:2025/3/16 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Problem B: 故障电灯(light) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 考慮對電燈進行差分:若第i個電燈和第i + 1個電燈狀態不同,則在第i個位置上放一個球
    這樣我們就放置了不超過2n個球,且必然是偶數個
    于是問題轉化為:有m個球,每一步可以把一個球平移奇質數個位置,兩個球位于相同位置則同時被消除,計算至
    少多少步能消除所有球
  • 然后我們發現, 假如兩個東西距離為奇質數cost為1, 偶數cost為二(哥德巴赫猜想), 其余奇數的話cost為3
  • 然后發現一種貪心方法, 是盡量匹配cost為1的, 然后分奇偶性各自用2覆蓋,看看最后剩下的那個直接判斷即可
#include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<iostream> #define ll long long #define mmp make_pair #define M using namespace std; int read() {int nm = 0, f = 1;char c = getchar();for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';return nm * f; } struct Edge{int v, c, nxt; }e[200010]; int head[10010], tot = 1; void build(int u, int v, int c) {e[++tot] = (Edge){v, c, head[u]}; head[u] = tot; return ; } void insert(int u, int v, int c) {build(u, v, c); build(v, u, 0); return ; } int dep[10010]; int S, T; queue<int> q; bool bfs() {memset(dep, 0, sizeof(dep)); dep[S] = 1; q.push(S); while(!q.empty()){int u = q.front(); q.pop(); for(int i = head[u]; i; i = e[i].nxt)if(!dep[e[i].v]&&e[i].c){dep[e[i].v] = dep[u] + 1; q.push(e[i].v); }}if(dep[T])return true; return false; } int cur[10010]; int dfs(int u, int flow) {if(u == T)return flow; for(int &i = cur[u]; i; i = e[i].nxt)if(e[i].c&&dep[e[i].v] == dep[u] + 1){int d = dfs(e[i].v, min(e[i].c, flow)); if(d){e[i].c -= d; e[i^1].c += d; return d; }}return 0; } int dinic() {int ans = 0; while(bfs()){for(int i = S; i <= T; i++)cur[i] = head[i]; int d; while(d = dfs(S, 1e9))ans += d; }return ans; } int prime[1000010], cnt; bool vis[10000010]; int x[1010]; int posx[1010], posy[1010]; int cnt1, cnt2; void push(int x) {if(x&1)posx[++cnt1] = x; else posy[++cnt2] = x; } int main(){int N = 10000000; vis[1] = true; for(int i = 2; i <= N; i++){if(!vis[i])prime[++cnt] = i; for(int j = 1; j <= cnt&&i * prime[j] <= N; j++){vis[i * prime[j]] = true; if(i%prime[j] == 0)break; }}vis[2] = true; int t = read();while(t--){memset(head, 0, sizeof(head)); cnt1 = cnt2 = 0; tot = 1; int n = read();for(int i = 1; i <= n; i++){x[i] = read(); if(i == 1||x[i - 1] != x[i] - 1)push(x[i]); if(i> 1&&x[i - 1] != x[i] - 1)push(x[i - 1] + 1); }push(x[n] + 1); S = 0, T = cnt1 + cnt2 + 1; for(int i = 1; i <= cnt1; i++)insert(S, i, 1); for(int i = 1; i <= cnt1; i++)for(int j = 1; j <= cnt2; j++)if(!vis[max(posx[i] - posy[j], posy[j] - posx[i])])insert(i, cnt1 + j, 1); for(int i = 1; i <= cnt2; i++)insert(cnt1 + i, T, 1); int ans = dinic(); printf("%d\n", ans + (cnt1 - ans)/2 * 2 + (cnt2 - ans)/2 * 2 + (cnt1 - ans)%2 * 3); }return 0; }

轉載于:https://www.cnblogs.com/luoyibujue/p/10719689.html

總結

以上是生活随笔為你收集整理的Problem B: 故障电灯(light)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。