日常訓練 20170603 棋盤

2021-08-02 05:57:58 字數 1718 閱讀 6666

給定乙個 n×

n 的棋盤,棋盤上每個位置要麼為空要麼為障礙。定義棋盤上兩個位置 (x

,y),

(u,v

) 能互相攻擊當前僅當滿足以下兩個條件: 1.x

=u或 y=

v 2.對於 (x

,y) 與 (u

,v) 之間的所有位置,均不是障礙。

現在有

q 個詢問,每個詢問給定 ki

,要求從棋盤中選出 ki

個空位置來放棋子,問最少互相能攻擊到的棋子對數是多少? n≤

50 , q≤

10000

, k≤

棋盤中空

位置數量

本來是道費用流大裸題,結果只有我沒想出來。考慮棋盤模型,一排表示行,一排表示列,然後棋子相互攻擊的貢獻是遞增的,所以

s 到表示行的點和 表示列的點到

t之間連遞增費用的邊,如果乙個位置不是障礙,就把對應行列連起來,障礙隔開的行和列只要建不同的點即可。

#include

const int n = 55;

const int p = n * n * 2;

const int inf = 1e9;

template void read(t &x)

int n, a[n][n], b[n][n], first[p], s, q[p + 10], dis[p], from[p], ans[n * n], cnt, line, s, t, q, x;

bool inq[p];

char ch[n][n];

struct edgemp[n*n

*n*n

*2];

void ins(int

x, int

y, int f, int v) ; first[x] = s;

mp[++s] = (edge) ; first[y] = s;

}bool spfa()

} }inq[q[head++]] = 0;

if (head > p) head = 1;

}return dis[t] < inf;

}void mcf(int i)

int main()

line = cnt;

for (int j=1; j <= n; j++)

for (int i=1; i <= n; i++)

s = 0; t = cnt + 1; s = 1;

for (int j=1; j <= n; j++)

for (int i=1; i <= n; i++)

if (ch[i][j] == '.')

ins(a[i][j], b[i][j], 1, 0);

for (int i=1; i <= line; i++)

for (int j=0; j < n; j++)

ins(s, i, 1, j);

for (int i=line + 1; i <= cnt; i++)

for (int j=0; j < n; j++)

ins(i, t, 1, j);

for (int i=1; spfa(); i++) mcf(i);

for (read(q); q--;)

read(x),

printf("%d\n", ans[x]);

return

0;}

程式設計訓練 棋盤

棋盤是指乙個行和列編號從1 n的nxn的二進位制矩陣,當行號和列號之和為偶數時該矩陣對應位置為黑色的 1 否則為白色的 0 以下圖示為n 1 2 3時的棋盤。給出乙個nxn的二進位制矩陣,請找出位於該矩陣內的最大尺寸的完整棋盤,以及最大尺寸棋盤的數量 棋盤可以交疊 每個測試用例的第一行是乙個正整數n...

日常訓練 壓縮

巨大的文字往往令人頭疼,特別是文字內容有大量重複的情況下,巨大的文字不便於運輸和閱讀,於是我們提出了noip nonsense obivous index pattern 荒謬的顯然索引法 一種 有效的 壓縮文字的方法。noip壓縮後的格式很特別,乙個文字壓縮後由若干個單元組成,每個單元由3部分組成...

日常訓練 Tree

j 對於h u j 時間複雜度的證明也是比較經典了,每次列舉的是sz eu s zev 相當於每次從a,b 中各任選一點,它們的lc a 為 u 這樣的點對列舉不會重複,因此總的時間複雜度為o n2 include include include include include using name...