1. 程式人生 > >Karen and Game

Karen and Game

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:
• 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 5
2 2 2 3 2
0 0 0 1 0
1 1 1 2 1

Output
4
row 1
row 1
col 4
row 3

Input
3 3
0 0 0
0 1 0
0 0 0

Output
-1

這道題的大意就是一個m*n的二維陣列初始為0,問最少經過幾次操作(每次操作可以每一行或每一列對應的每個數加1)得到給出的二維陣列並輸出操作過程(多種可能性輸出任意一種即可)。

如果列數大於行數,說明是一個扁的二維陣列,找到每一行的最小值並記錄(用於對行的輸出),把該行所有數減去這個最小值;現在每一行的每個數之和應該相等,[若不相等輸出-1(證明不能操作成功)]只看第一行進行對列的輸出即可。
如果行數大於列數,說明是一個瘦高的二維陣列,進行類似的操作即可。

#include<iostream>
#include<string.h>
using namespace std;
int grid[510][510];
int mmin[510],sum[510];
int main(){
    int col,roo;
    while(cin>>roo>>col){
        memset(grid,0,sizeof(grid));
        memset(sum,0,sizeof(sum));
        for(int i=0;i<510;i++)
            mmin[i]=9999;
        for(int i=0;i<roo;i++)
            for(int j=0;j<col;j++)
                cin>>grid[i][j];

        int chose=max(roo,col);
        int ans=0;
        if(chose==col){
            for(int i=0;i<roo;i++)
                for(int j=0;j<col;j++)
                    if(grid[i][j]<mmin[i]) mmin[i]=grid[i][j];
            for(int i=0;i<roo;i++){
                ans=ans+mmin[i];
                for(int j=0;j<col;j++){
                        grid[i][j]=grid[i][j]-mmin[i];
                        sum[i]=sum[i]+grid[i][j];
                    }
            }
            for(int i=1;i<roo;i++)          
                if(sum[i]!=sum[i-1]){ 
                    ans=-1;break;           
            }
            if(ans==-1){
                cout<<"-1"<<endl;
                continue;
            }            
            for(int j=0;j<col;j++){
                if(grid[0][j]!=0){
                    ans=ans+grid[0][j];
                }
            }
            cout<<ans<<endl;
            for(int i=0;i<roo;i++){
                for(int j=0;j<mmin[i];j++)
                    cout<<"row "<<i+1<<endl;
            }
            for(int j=0;j<col;j++){
                if(grid[0][j]!=0){              
                    for(int i=0;i<grid[0][j];i++){
                        cout<<"col "<<j+1<<endl;
                    }
                }
            }
        }
        else{

            for(int i=0;i<col;i++)
                for(int j=0;j<roo;j++)
                    if(grid[j][i]<mmin[i]) mmin[i]=grid[j][i];
            for(int i=0;i<col;i++){
                ans=ans+mmin[i];
                for(int j=0;j<roo;j++){
                        grid[j][i]=grid[j][i]-mmin[i];
                        sum[i]=sum[i]+grid[j][i];
                    }
            }
            for(int i=1;i<col;i++)          
                if(sum[i]!=sum[i-1]){ 
                    ans=-1;break;           
            }
            if(ans==-1){
                cout<<"-1"<<endl;
                continue;
            }            
            for(int j=0;j<roo;j++){
                if(grid[j][0]!=0){
                    ans=ans+grid[j][0];
                }
            }
            cout<<ans<<endl;
            for(int i=0;i<col;i++){
                for(int j=0;j<mmin[i];j++)
                    cout<<"col "<<i+1<<endl;
            }
            for(int j=0;j<roo;j++){
                if(grid[j][0]!=0){              
                    for(int i=0;i<grid[j][0];i++){
                        cout<<"row "<<j+1<<endl;
                    }
                }
            }
        }           
    }

    return 0;
}

然而這種寫法程式碼冗長,而且寫迴圈控制位置的時候容易出錯,於是想到了二維陣列的轉置。

#include<iostream>
#include<string.h>
using namespace std;
int grid[510][510];
int temp[510][510]; 
int mmin[510],sum[510];
int main(){
    int col,roo;
    while(cin>>roo>>col){
        memset(grid,0,sizeof(grid));
        memset(sum,0,sizeof(sum));
        for(int i=0;i<510;i++)
            mmin[i]=9999;
        for(int i=0;i<roo;i++)
            for(int j=0;j<col;j++)
                cin>>temp[i][j];

        int chose=max(roo,col);
        int ans=0;
        int det=0;
        if(chose==roo){
            //轉置並交換行列數 併為轉置變數賦值為1 
            for(int i=0;i<roo;i++)
                for(int j=0;j<col;j++)
                    grid[j][i]=temp[i][j];   
            int tttemp=col;col=roo;roo=tttemp;  
            det=1;

        }
        else 
            for(int i=0;i<roo;i++)
                for(int j=0;j<col;j++)
                    grid[i][j]=temp[i][j];//直接賦值過去 

        //開始計算 
        for(int i=0;i<roo;i++)
                for(int j=0;j<col;j++)
                    if(grid[i][j]<mmin[i]) mmin[i]=grid[i][j];
            for(int i=0;i<roo;i++){
                ans=ans+mmin[i];
                for(int j=0;j<col;j++){
                        grid[i][j]=grid[i][j]-mmin[i];
                        sum[i]=sum[i]+grid[i][j];
                    }
            }
            for(int i=1;i<roo;i++)          
                if(sum[i]!=sum[i-1]){ 
                    ans=-1;break;           
            }
            if(ans==-1){
                cout<<"-1"<<endl;
                continue;
            }            
            for(int j=0;j<col;j++){
                if(grid[0][j]!=0){
                    ans=ans+grid[0][j];
                }
            }
            cout<<ans<<endl;
            for(int i=0;i<roo;i++){
                for(int j=0;j<mmin[i];j++)
                det?cout<<"col "<<i+1<<endl:cout<<"row "<<i+1<<endl; //判斷是否轉置過 控制相應輸出 注意這裡是i                    
            }
            for(int j=0;j<col;j++){
                if(grid[0][j]!=0){              
                    for(int i=0;i<grid[0][j];i++){
                        det?cout<<"row "<<j+1<<endl:cout<<"col "<<j+1<<endl;//判斷是否轉置過 控制相應輸出 注意這裡是j
                    }
                }
            }       
    }
    return 0;
}