題意:
給你一個n*n的0,1矩陣,要求你操作最少的0邊成1,1不能變,使得n*n的矩陣變成偶數矩陣,也就是任意的一個矩陣內的元素,其上,下,左,右元素(如果存在的話)的和位偶數
分析:
最簡單的想法就是暴力想法,也就是枚舉每個0,變或不變,其運算量極大,在本題目的承受範圍內不能理想的運行出結果
其實確定了第一行就可以確定第二行了,爲什麼?自己好好想想,不難
如果這樣想的話,只需要枚舉一行的所有情況就可以了,這樣的時間複雜度爲O(2^n*n^2).
Code:
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define DIR 4
#define DIM 2
#define STATUS 2
#define CNT 15
#define MAXM 100000 + 10
#define oo (~0u)>>1
#define INF 0x3F3F3F3F
#define REPI(i, s, e) for(int i = s; i <= e; i ++)
#define REPD(i, e, s) for(int i = e; i >= s; i --)
static const double EPS = 1e-5;
int rst;
int f[CNT+1], t[CNT+1][CNT+1], g[CNT+1][CNT+1];
inline int judge(int n)
{
int cost = 0;
memset(t[0], 0, sizeof(t[0]));
REPI(i, 1, n) {
t[1][i] = f[i];
}
REPI(i, 1, n) {
if( f[i] && !g[1][i] ) {
cost += 1;
}
if( !f[i] && g[1][i] ) {
return INF;
}
}
REPI(i, 1, n-1) {
REPI(j, 1, n) {
int s = t[i-1][j];
if( 1 != j ) {
s += t[i][j-1];
}
if( n != j ) {
s += t[i][j+1];
}
if( s&1 ) {
if( !g[i+1][j] ) {
cost += 1, t[i+1][j] = 1;
}
else {
t[i+1][j] = 1;
}
}
else {
if( g[i+1][j] ) {
return INF;
}
else {
t[i+1][j] = 0;
}
}
}
}
return cost;
}
inline void dfs(int curs, int tar)
{
if( curs > tar ) {
rst = min(rst, judge(tar));
return;
}
f[curs] = 0, dfs(curs+1, tar);
f[curs] = 1, dfs(curs+1, tar);
}
int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int cas, n;
scanf("%d", &cas);
REPI(k, 1, cas) {
scanf("%d", &n);
memset(g, 0, sizeof(g));
REPI(i, 1, n) {
REPI(j, 1, n) {
scanf("%d", &g[i][j]);
}
}
rst = INF, dfs(1, n);
printf("Case %d: %d\n", k, INF == rst? -1 : rst);
}
return 0;
}
uva_11464_Even Parity(枚舉,暴力)
最新推荐文章于 2020-03-02 16:45:21 发布