标签:ons spl input build http nsis print 暴力 har
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:
If there are multiple optimal solutions, output any one of them.
Examples
3 5
2 2 2 3 2
0 0 0 1 0
1 1 1 2 1
4
row 1
row 1
col 4
row 3
3 3
0 0 0
0 1 0
0 0 0
-1
3 3
1 1 1
1 1 1
1 1 1
3
row 1
row 2
row 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‘; } } }
Karen and Game CodeForces - 816C (暴力+构造)
标签:ons spl input build http nsis print 暴力 har
原文地址:https://www.cnblogs.com/qieqiemin/p/10323009.html