816C. Karen and Game 贪心
题意:给出n*m的矩阵图,现有对行或对列上的数减1的操作,问最少几步使所有数变为0,无解输出-1
思路:贪心暴力即可。先操作行和先操作列结果可能不同注意比较。
/** @Date : 2017-07-01 10:22:53 * @FileName: 816C.cpp * @Platform: Windows * @Author : Lweleth (SoungEarlf@gmail.com) * @Link : https://github.com/ * @Version : $Id$ */ #include <bits/stdc++.h> #define LL long long #define PII pair #define MP(x, y) make_pair((x),(y)) #define fi first #define se second #define PB(x) push_back((x)) #define MMG(x) memset((x), -1,sizeof(x)) #define MMF(x) memset((x),0,sizeof(x)) #define MMI(x) memset((x), INF, sizeof(x)) using namespace std; const int INF = 0x3f3f3f3f; const int N = 1e5+20; const double eps = 1e-8; int n, m, cnt1, cnt2; int a[110][110], b[110][110]; int r1[2][110]; int r2[2][110]; void debug() { for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) printf("%d", a[i][j]); printf("\n"); } } int main() { while(cin >> n >> m) { cnt1 = cnt2 = 0; MMF(r1); MMF(r2); for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { scanf("%d", &a[i][j]); b[i][j] = a[i][j]; } } int mi; for(int k = 0; k < 2; k++) { for(int i = 0; i < n; i++) { mi = INF; for(int j = 0; j < m; j++) if(k) mi = min(mi, a[j][i]); else mi = min(mi, a[i][j]); for(int j = 0; j < m; j++) if(k) a[j][i] -= mi; else a[i][j] -= mi; r1[k][i]= mi; cnt1+=mi; } swap(n, m); } //debug(); for(int k = 0; k < 2; k++) { for(int i = 0; i < m; i++) { mi = INF; for(int j = 0; j < n; j++) if(k) mi = min(mi, b[i][j]); else mi = min(mi, b[j][i]); for(int j = 0; j < n; j++) if(k) b[i][j] -= mi; else b[j][i] -= mi; r2[k^1][i] = mi; cnt2+=mi; } swap(n, m); } //debug(); for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) { if(a[i][j]) cnt1 = -1; if(b[i][j]) cnt2 = -1; } if(cnt1 <= cnt2 && cnt1 >= 0) { printf("%d\n", cnt1); for(int i = 0; i < n; i++) while(r1[0][i]--) printf("row %d\n", i + 1); for(int i = 0; i < m; i++) while(r1[1][i]--) printf("col %d\n", i + 1); } else if(cnt2 <= cnt1 && cnt2 >= 0) { printf("%d\n", cnt2); for(int i = 0; i < n; i++) while(r2[0][i]--) printf("row %d\n", i + 1); for(int i = 0; i < m; i++) while(r2[1][i]--) printf("col %d\n", i + 1); } else if(cnt1 == -1 && cnt2 >= 0) { printf("%d\n", cnt2); for(int i = 0; i < n; i++) while(r2[0][i]--) printf("row %d\n", i + 1); for(int i = 0; i < m; i++) while(r2[1][i]--) printf("col %d\n", i + 1); } else if(cnt2 == -1 && cnt1 >= 0) { printf("%d\n", cnt1); for(int i = 0; i < n; i++) while(r1[0][i]--) printf("row %d\n", i + 1); for(int i = 0; i < m; i++) while(r1[1][i]--) printf("col %d\n", i + 1); } else printf("-1\n"); } return 0; }