标签:acm
看这个问题之前,可以先看看这个论文《一类算法复合的方法》,说白了就是分类讨论,但是这个思想很重要
const int MAXN = 110;
int ipt[MAXN][MAXN];
int main()
{
// freopen("in.txt", "r", stdin);
int n, m, k;
while (~RIII(n, m, k))
{
REP(i, n) REP(j, m) RI(ipt[i][j]);
if (n < m)
{
REP(i, n) FF(j, i + 1, m) swap(ipt[i][j], ipt[j][i]);
swap(n, m);
}
if (n > k)
{
int ans = INF;
REP(i, n)
{
int tans = 0;
REP(j, n)
{
int cnt = 0;
if (i == j) continue;
REP(k, m)
{
if (ipt[i][k] != ipt[j][k]) cnt++;
}
tans += min(cnt, m - cnt);
}
ans = min(ans, tans);
}
printf("%d\n", ans <= k ? ans: -1);
}
else
{
int ans = INF;
REP(i, n)
{
int all = 1 << m;
for (int q = 0; q < all; q++)
{
int diff = 0;
for (int t = 0, l = 1; t < m; l <<= 1, t++) if (((q & l) != 0) != ipt[i][t]) diff++;
if (diff > k) continue;
int tans = 0;
REP(j, n)
{
if (i == j) continue;
int cnt = 0;
for (int t = 0, l = 1; t < m; t++, l <<= 1) if (((q & l) != 0) != ipt[j][t]) cnt++;
tans += min(cnt, m - cnt);
}
ans = min(ans, diff + tans);
}
}
printf("%d\n", ans <= k ? ans: -1);
}
}
return 0;
}
参照大神的代码后的一些细节修改:
const int MAXN = 110;
int ipt[MAXN][MAXN];
int main()
{
// freopen("in.txt", "r", stdin);
int n, m, k;
while (~RIII(n, m, k))
{
int ans = INF, all = 1 << m;
REP(i, n) REP(j, m) RI(ipt[i][j]);
if (n < m)
{
REP(i, n) FF(j, i + 1, m) swap(ipt[i][j], ipt[j][i]);
swap(n, m);
}
if (n > k)
{
REP(i, n)
{
int tans = 0;
REP(j, n)
{
int cnt = 0;
REP(k, m)
cnt += ipt[i][k] ^ ipt[j][k];
tans += min(cnt, m - cnt);
}
ans = min(ans, tans);
}
}
else
{
for (int mask = 0; mask < all; mask++)
{
int tans = 0;
REP(i, n)
{
int cnt = 0;
REP(j, m) cnt += ipt[i][j] ^ (mask >> j & 1);
tans += min(cnt, m - cnt);
}
ans = min(ans, tans);
}
}
printf("%d\n", ans <= k ? ans: -1);
}
return 0;
}
Codeforces Round #243 (Div. 2)——Sereja and Table
标签:acm
原文地址:http://blog.csdn.net/wty__/article/details/24665383