CodeForces 816C 思维
Posted daybreaking
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces 816C 思维相关的知识,希望对你有一定的参考价值。
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 m columns. 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:
- rowx, (1?≤?x?≤?n) describing a move of the form "choose the x-th row".
- colx, (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.
Sample Input
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
Hint
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.
分析这种棋盘的特性,要加加一行,要加加一列,且不能减,且棋盘初始都为零。所以如果同一行上出现了不同的数,则数大的一列必然有该列的加,行同理。
所以可以先处理列,把所有列加过的都还原回去,所以只剩下了由个别的行改变所导致的棋盘,再用同样的方法将行还原回去,最后如果棋盘仍然不为零的话,说明所有的行都进行过相同次数的
加(这里要注意!!!如果最后棋盘不为零的话,既有可能是所有的行进行了操作,也有可能是所有的列进行了操作,因为题目让求最少的操作次数,所以应判断行和列谁小操作的谁)。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<string> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<stack> 9 #include<deque> 10 #include<map> 11 #include<iostream> 12 using namespace std; 13 typedef long long LL; 14 const double pi=acos(-1.0); 15 const double e=exp(1); 16 const int N = 100009; 17 18 LL con[110][110]; 19 LL check[110][110]; 20 LL col[110],row[110]; 21 22 int main() 23 { 24 LL i,p,j,m,n; 25 LL flag=0; 26 scanf("%lld%lld",&m,&n); 27 LL head=10000000,tail=10000000,mid; 28 29 for(i=1; i<=m; i++) 30 { 31 for(j=1; j<=n; j++) 32 { 33 scanf("%lld",&con[i][j]); 34 if(con[1][j]<head) 35 head=con[1][j]; 36 if(con[i][1]<tail) 37 tail=con[i][1]; 38 } 39 } 40 41 if(m<=n) 42 { 43 for(i=1; i<=n; i++) 44 { 45 if(con[1][i]>head) 46 col[i]+=con[1][i]-head; 47 } 48 mid=tail-col[1]; 49 for(i=1; i<=m; i++) 50 { 51 if(con[i][1]>tail) 52 row[i]+=con[i][1]-tail; 53 row[i]+=mid; 54 } 55 } 56 else 57 { 58 for(i=1; i<=m; i++) 59 { 60 if(con[i][1]>tail) 61 row[i]+=con[i][1]-tail; 62 } 63 mid=head-row[1]; 64 for(i=1; i<=n; i++) 65 { 66 if(con[1][i]>head) 67 col[i]+=con[1][i]-head; 68 col[i]+=mid; 69 } 70 } 71 72 flag=0; 73 74 for(i=1; i<=n; i++) 75 { 76 if(col[i]) 77 { 78 flag+=col[i]; 79 for(j=1; j<=m; j++) 80 check[j][i]+=col[i]; 81 } 82 } 83 for(i=1; i<=m; i++) 84 { 85 if(row[i]) 86 { 87 flag+=row[i]; 88 for(j=1; j<=n; j++) 89 check[i][j]+=row[i]; 90 } 91 } 92 93 for(i=1; i<=m; i++) 94 { 95 for(j=1; j<=n; j++) 96 { 97 if(con[i][j]!=check[i][j]) 98 break; 99 } 100 if(j<=n) 101 { 102 flag=-1; 103 break; 104 } 105 } 106 107 108 109 if(flag==-1) 110 printf("-1 "); 111 else 112 { 113 printf("%lld ",flag); 114 for(i=1; i<=n; i++) 115 { 116 while(col[i]) 117 { 118 col[i]--; 119 printf("col %lld ",i); 120 } 121 } 122 for(i=1; i<=m; i++) 123 { 124 while(row[i]) 125 { 126 row[i]--; 127 printf("row %lld ",i); 128 } 129 } 130 } 131 return 0; 132 }
以上是关于CodeForces 816C 思维的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces - 816C Karen and Game(简单模拟)
CodeForces 1005D Polycarp and Div 3(思维贪心dp)
CodeForces - 1251C (思维+贪心+归并排序)
[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段