zoukankan      html  css  js  c++  java
  • CodeForces #419(div2)C. 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
    input
    3 3
    1 1 1
    1 1 1
    1 1 1
    output
    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.

    通过思考,有以下规则:

    1.一行中最小的数字,就是能对该行执行的最大操作次数,如2 3 4 3,最多操作2次后变为0 1 2 1,此后对该行无法继续操作,对于列也是一样。

    2.若对所有行执行操作,等价于对所有列执行操作

    3.把对所有行或所有列的同步操作优先进行,可以达到最简化的效果

    最简化操作以行列数量为准,如n=2,m=4,数组如下

    k+0,k+0,k+1,k+0

    k+2,k+2,k+3,k+2

    若要先消除k,操作行,使数组总和-m,操作列,使数组总和-n,因此行数少,则优先列,列数少,则操作行

     4.对于最简化后的数组,其任意数字等于其最大行操作数与最大列操作数之和。如上述例子

    0 0 1 0

    2 2 3 2

    第二行为2,第三列为1,其余全为0

    代码如下

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<set>
    using namespace std;
    const int MAX=1e5+10;
    #define INF 0x7fffffff
    #define ll long long
    #define FOR(i,n) for(i=1;i<=n;i++)
    
    int main()
    {
        int n,m,i,j,k,ans=0,a[105][105],row[105],col[105],mark1;
        cin>>n>>m;
        for(i=1;i<=n;i++)
        {
            row[i]=INF;
            for(j=1;j<=m;j++)
            {
                cin>>a[i][j];
                row[i]=min(row[i],a[i][j]);
            }
        }
        for(i=1;i<=m;i++)
        {
            col[i]=INF;
            for(j=1;j<=n;j++)
            {
                col[i]=min(col[i],a[j][i]);
            }
        }
        if(n>m)
        {
            mark1=INF;
            for(i=1;i<=m;i++)
            {
                ans+=col[i];
                mark1=min(mark1,col[i]);
            }
            for(i=1;i<=n;i++)
            {
                row[i]-=mark1;
                ans+=row[i];
            }
        }
        else
        {
            mark1=INF;
            for(i=1;i<=n;i++)
            {
                ans+=row[i];
                mark1=min(mark1,row[i]);
            }
            for(i=1;i<=m;i++)
            {
                col[i]-=mark1;
                ans+=col[i];
            }
        }
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=m;j++)
            {
                if(a[i][j]!=(col[j]+row[i]))
                {
                    cout<<"-1"<<endl;
                    return 0;
                }
            }
        }
        if(n>m)
        {
            cout<<ans<<endl;
            for(i=1;i<=m;i++)
                for(j=1;j<=col[i];j++)
                cout<<"col "<<i<<endl;
            for(i=1;i<=n;i++)
                for(j=1;j<=row[i];j++)
                cout<<"row "<<i<<endl;    
        }
        else
        {
            cout<<ans<<endl;
            for(i=1;i<=n;i++)
                for(j=1;j<=row[i];j++)
                cout<<"row "<<i<<endl;
            for(i=1;i<=m;i++)
                for(j=1;j<=col[i];j++)
                cout<<"col "<<i<<endl;
        }
    }
  • 相关阅读:
    hdu 4297 One and One Story 夜
    hdu 4280 Island Transport 夜
    1389. Roadworks 夜
    hdu 4289 Control 夜
    hdu 4291 A Short problem 夜
    hdu 4284 Travel 夜
    1080. Map Coloring 夜
    正则中的转义符\
    起重复出现作用的量词*和+
    安卓的权限大全和动态使用安卓权限
  • 原文地址:https://www.cnblogs.com/qq936584671/p/7043762.html
Copyright © 2011-2022 走看看