清華大學演算法訓練營 象棋

2021-08-22 08:31:52 字數 1566 閱讀 2828

你有足夠多的象棋「車」,在乙個n×n的棋盤上你能放多少個「車」呢?注意,所給棋盤上有些位置不能放任何東西。同時,某一行(列)最多只能存在乙個「車」。

第一行為乙個正整數n。(1<=n<=500 )

接下來n行,每行包含n個整數,若為0表示這個位置不能放「車」;若為1表示這個位置可以放「車」。

輸出乙個整數,表示最多能放多少個「車」。

5

1 0 0 0 0

0 0 0 0 0

0 0 0 1 0

1 1 0 1 0

0 0 0 1 0

3
將行看作x集合,列看作y集合

若棋盤上為1的位置有(i,j),則x集的第i個點向y集的第j個點連邊

#include

using namespace std;

const

int n =

505*

2, m= n * n;

struct ee[m]

;//ihead:鄰接表的頭

//cnt:鄰接表大小

//mc:表示每個點所匹配到的另乙個點match

//vis:y集元素是否被訪問過

int cnt,ihead[n]

,mc[n]

;bool vis[n]

;//鄰接錶連邊,表示連一條x到y的有向邊

//x:起點

//y:終點

void

add(

int x,

int y)

//匈牙利演算法

//x:x集上的點,從當前點出發找增廣路

//返回值:若找到增廣路則返回true,否則返回false

bool dfs

(int x)}}

return false;

}// 求解棋盤上最多能放多少個「車」

// n:棋盤的大小為n×n的

// board:所給棋盤,對於某個位置上的數:若值為1表示可以放「車」;若值為0表示不能放「車」

// 返回值:能放「車」的最大個數

intgetanswer

(int n, vectorint>> board)

//連邊

for(

int i =

1; i <= n;

++i)

for(

int j =

1; j <= n;

++j)

if(board[i-1]

[j-1]==

1)add(i,j+n)

;int ans =0;

for(

int i=

1; i<=n;

++i)if(

!mc[i]

)return ans;

}int

main()

e.push_back

(t);

}printf

("%d\n"

,getanswer

(n, e));

return0;

}

清華大學演算法訓練營 等式

時間限制 2s,空間256mb 問題描述 n個變數和m個 相等 或 不相等 的約束條件,請你判定是否存在一種賦值方案滿足所有m個約束條件。輸入第一行乙個整數t,表示資料組數。t 100 接下來會有t組資料,對於每組資料 第一行是兩個整數n,m,表示變數個數和約束條件的個數。1 n,m 500000 ...

清華大學演算法訓練營 重編碼

重編碼 priority queue 有一篇文章,文章包含 n種單詞,單詞的編號從 1 至 n,第 i 種單詞的出現次數為 w i 現在,我們要用乙個 2 進製串 即只包含 0 或 1 的串 s i 來替換第 i 種單詞,使其滿足如下要求 對於任意的 1 i,j n i j 都有 s i 不是 s ...

清華大學演算法訓練營 序列計數

給定乙個n個整數的序列以及乙個非負整數d,請你輸出這個序列中有多少個連續子串行 長度大於1 滿足該子串行的最大值最小值之差不大於d。如 序列1 2 3中長度大於1的連續子串行有 1 2 2 31 2 3第一行包含兩個整數n,d。1 n 300000,0 d 2000000000 接下來一行包含n個整...