题目大意:给出若干个骨牌,有00, 01, 10, 11四种骨牌,要求重排后,每一竖的上1的个数的最大值最小。
解题思路:贪心,奇数行从1~m放,偶数行从m~1放,均从11先放,在放10,和01(01和10是一样的,因为可以旋转),注意奇数行01,偶数就得10.
#include <stdio.h>
#include <string.h>
const int N = 1e3+10;
const int M = 4;
const char sign[M][M] = { "00", "01", "10", "11"};
int n, m, c[M], g[N][N];
void init() {
char str[M];
memset(g, 0, sizeof(g));
memset(c, 0, sizeof(c));
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%s", str);
if (str[0] == ‘1‘ && str[1] == ‘1‘) c[2]++;
else if (str[0] == ‘0‘ && str[1] == ‘0‘) c[0]++;
else c[1]++;
}
}
}
void set() {
for (int i = 0; i < n; i++) {
if (i&1) {
for (int j = m-1; j >= 0; j--) {
if (c[2]) {
g[i][j] = 3;
c[2]--;
} else if (c[1]) {
g[i][j] = 1;
c[1]--;
}
if (c[1] == 0 && c[2] == 0) return;
}
} else {
for (int j = 0; j < m; j++) {
if (c[2]) {
g[i][j] = 3;
c[2]--;
} else if (c[1]) {
g[i][j] = 2;
c[1]--;
}
if (c[1] == 0 && c[2] == 0) return ;
}
}
}
}
void solve() {
set();
for (int i = 0; i < n; i++) {
printf("%s", sign[g[i][0]]);
for (int j = 1; j < m; j++) printf(" %s", sign[g[i][j]]);
printf("\n");
}
}
int main () {
init();
solve();
return 0;
}
原文:http://blog.csdn.net/keshuai19940722/article/details/19605951