校內訓練0611 矩陣
阿新 • • 發佈:2017-06-11
cin b16 c++ 要花 int ++ else 構造 枚舉
【題目大意】
給一個n*n的矩陣,每個位置為0或1。每次可以選擇一行和一列,把那列完全賦值為那行的值。求最少多少步使得全為1.
無解輸出-1。
n <= 1000
【題解】
發現只有全空才是無解,否則考慮構造。
每一列,只要有0的格子都需要被賦值1次,所以設有x列有含有0的格子,則至少要賦值x次。
現在我們就需要一個全1的行來給這些有0的列賦值。
考慮構造一個全1的行。我們枚舉第i行,假裝要把他弄成全1的。
設第i行的0的數量為y,那麽考慮第i列是否含有1,如果含有1那麽就可以用含有1的那列的那行給第i行所有0的地方賦值,需要y步。
如果第i列不含有1,我們要花1次操作給第i列搞個1出來,所以答案是y+1步。
取最小值即可。
這簽到題我怎麽沒做出來啊。。
# include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 1e3 + 10; const int mod = 1e9+7View Code; # define RG register # define ST static int n, a[M]; char mp[M][M]; bool hv[M]; int main() { // freopen("matrix.in", "r", stdin); // freopen("matrix.out", "w", stdout); cin >> n; for (int i=1; i<=n; ++i) scanf("%s", mp[i]+1); bool all = 1; for (int i=1; i<=n; ++i)for (int j=1; j<=n; ++j) all &= (mp[i][j] == ‘.‘); if(all) { puts("-1"); return 0; } int ans = 0; for (int i=1; i<=n; ++i) { bool have = 0; for (int j=1; j<=n; ++j) { if(mp[j][i] == ‘.‘) { have = 1; break; } } ans += have; for (int j=1; j<=n; ++j) if(mp[j][i] == ‘#‘) hv[i] = 1; } int tmp = 1e9; for (int i=1; i<=n; ++i) { // for one line int cur = 0; for (int j=1; j<=n; ++j) cur += (mp[i][j] == ‘.‘); if(cur == 0 || hv[i]) tmp = min(tmp, cur); else tmp = min(tmp, cur+1); } cout << ans + tmp; return 0; }
校內訓練0611 矩陣