On the way to school, Karen became fixated on the puzzle game on her phone!
The game is played as follows. In each level, you have a grid with n rows and mcolumns. Each cell originally contains the number 0.
One move consists of choosing one row or column, and adding 1 to all of the cells in that row or column.
To win the level, after all the moves, the number in the cell at the i-th row and j-th column should be equal to gi, j.
Karen is stuck on one level, and wants to know a way to beat this level using the minimum number of moves. Please, help her with this task!
Input
The first line of input contains two integers, n and m (1 ≤ n, m ≤ 100), the number of rows and the number of columns in the grid, respectively.
The next n lines each contain m integers. In particular, the j-th integer in the i-th of these rows contains gi, j (0 ≤ gi, j ≤ 500).
Output
If there is an error and it is actually not possible to beat the level, output a single integer -1.
Otherwise, on the first line, output a single integer k, the minimum number of moves necessary to beat the level.
The next k lines should each contain one of the following, describing the moves in the order they must be done:
- row x, (1 ≤ x ≤ n) describing a move of the form "choose the x-th row".
- col x, (1 ≤ x ≤ m) describing a move of the form "choose the x-th column".
If there are multiple optimal solutions, output any one of them.
Examples
Input
3 52 2 2 3 20 0 0 1 01 1 1 2 1
Output
4row 1row 1col 4row 3
Input
3 30 0 00 1 00 0 0
Output
-1
Input
3 31 1 11 1 11 1 1
Output
3row 1row 2row 3
Note
In the first test case, Karen has a grid with 3 rows and 5 columns. She can perform the following 4 moves to beat the level:
In the second test case, Karen has a grid with 3 rows and 3 columns. It is clear that it is impossible to beat the level; performing any move will create three 1s on the grid, but it is required to only have one 1 in the center.
In the third test case, Karen has a grid with 3 rows and 3 columns. She can perform the following 3 moves to beat the level:
Note that this is not the only solution; another solution, among others, is col 1, col 2, col 3.
题目链接:
题意:
给定一个n*m的矩阵,
每一个操作你可以选择一行或者一列,使该行或列的数值全部加1,求使用最小的操作次数使一个全部为0的矩阵变成给定矩阵,
如果不可能实现请输出-1.
思路:
预处理出每一行和每一列的最小值,
然后以n和m的关系进行分类处理,
如果n<=m,就先处理行再处理列,这样可以用最小的次数,
反而反之。
举例:
1 1 1 1
1 1 1 1
1 1 1 1
如果先处理列,就要4次,处理行只需要3次。
接下来:
如果每一行或列的最小值大于0,那么我们就可以处理最小值次,然后每一次处理,暴力的把数组中的对应元素减去1,
行和列全部处理好后,去n*m扫一边数组,如果还有数大于0,那么就是无法实现的情况。
每一步具体为什么可能需要大家自己好好思考。
细节见我的代码。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <vector> #define sz(a) int(a.size()) #define all(a) a.begin(), a.end() #define rep(i,x,n) for(int i=x;i<n;i++) #define repd(i,x,n) for(int i=x;i<=n;i++) #define pii pair<int,int> #define pll pair<long long ,long long> #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define MS0(X) memset((X), 0, sizeof((X))) #define MSC0(X) memset((X), ‘\0‘, sizeof((X))) #define pb push_back #define mp make_pair #define fi first #define se second #define eps 1e-6 #define gg(x) getInt(&x) #define db(x) cout<<"== [ "<<x<<" ] =="<<endl; using namespace std; typedef long long ll; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll lcm(ll a,ll b){return a/gcd(a,b)*b;} ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;} inline void getInt(int* p); const int maxn=1000010; const int inf=0x3f3f3f3f; /*** TEMPLATE CODE * * STARTS HERE ***/ int a[550][550]; int sumr[550]; int sumc[550]; int n,m; void buildr(int x) { repd(i,1,n) { repd(j,1,m) { if(i==x) { a[i][j]--; } } } } void buildl(int x) { repd(i,1,n) { repd(j,1,m) { if(j==x) { a[i][j]--; } } } } int main() { gg(n); gg(m); repd(i,1,n) { repd(j,1,m) { gg(a[i][j]); } } repd(i,1,m) { int cnt=inf; repd(j,1,n) { cnt=min(cnt,a[j][i]); } sumc[i]=cnt; } repd(i,1,n) { int cnt=inf; repd(j,1,m) { cnt=min(cnt,a[i][j]); } sumr[i]=cnt; } int ans=0; int flag=0; int fu=0; std::vector<int> r; std::vector<int> c; if(n<=m) { repd(i,1,n) { while(sumr[i]) { r.pb(i); ans++; sumr[i]--; buildr(i); } } repd(i,1,m) { int cnt=inf; repd(j,1,n) { cnt=min(cnt,a[j][i]); } sumc[i]=cnt; } repd(i,1,m) { while(sumc[i]) { c.pb(i); ans++; sumc[i]--; buildl(i); } } // repd(i) }else { repd(i,1,m) { while(sumc[i]) { c.pb(i); ans++; sumc[i]--; buildl(i); } } repd(i,1,n) { int cnt=inf; repd(j,1,m) { cnt=min(cnt,a[i][j]); } sumr[i]=cnt; } repd(i,1,n) { while(sumr[i]) { r.pb(i); ans++; sumr[i]--; buildr(i); } } } repd(i,1,n) { repd(j,1,m) { if(a[i][j]<0) { fu=min(fu,a[i][j]); } if(a[i][j]!=0) { flag=1; break; } } } if(flag) { printf("-1"); return 0; } printf("%d\n",ans ); repd(i,0,sz(r)-1) { int x=r[i]; printf("row %d\n",x); } repd(i,0,sz(c)-1) { int x=c[i]; printf("col %d\n", x); } // db(fu); return 0; } inline void getInt(int* p) { char ch; do { ch = getchar(); } while (ch == ‘ ‘ || ch == ‘\n‘); if (ch == ‘-‘) { *p = -(getchar() - ‘0‘); while ((ch = getchar()) >= ‘0‘ && ch <= ‘9‘) { *p = *p * 10 - ch + ‘0‘; } } else { *p = ch - ‘0‘; while ((ch = getchar()) >= ‘0‘ && ch <= ‘9‘) { *p = *p * 10 + ch - ‘0‘; } } }
原文地址:https://www.cnblogs.com/qieqiemin/p/10323009.html