Codeforces C1. Binary Table (Easy Version) (#684 Div.2) (思维&模拟)

传送门

题意: 有一个nm的01矩阵,每次操作可选其中2 * 2子矩阵的任意3个元素取反,要求将所有元素变成0,且操作次数在3n*m以内(保证存在答案)。
输出操作的总次数及每次操作对应的元素下标。
在这里插入图片描述
思路: 分两个部分处理 (100+行的模拟,比赛的时候wa了6发,我直接呜呜了)

  • 先暴力处理前(n-1)*m个位置,即每次把’1’放在正反L的’头’(即上一层单出来那个)。
  • 再单独处理最后一层,每次都看第j和j+1个位置。将是’11’型,'10’型和最后一个元素’01’型分类讨论。
  • 这样修改次数约为n*m+次(最后一行的操作次数较多)。

代码实现:

#include<bits/stdc++.h>
#define endl '\n'
#define null NULL
#define ll long long
#define int long long
#define pii pair<int, int>
#define lowbit(x) (x &(-x))
#define ls(x) x<<1
#define rs(x) (x<<1+1)
#define me(ar) memset(ar, 0, sizeof ar)
#define mem(ar,num) memset(ar, num, sizeof ar)
#define rp(i, n) for(int i = 0, i < n; i ++)
#define rep(i, a, n) for(int i = a; i <= n; i ++)
#define pre(i, n, a) for(int i = n; i >= a; i --)
#define IOS ios::sync_with_stdio(0); cin.tie(0);cout.tie(0);
const int way[4][2] = {
    
    {
    
    1, 0}, {
    
    -1, 0}, {
    
    0, 1}, {
    
    0, -1}};
using namespace std;
const int  inf = 0x7fffffff;
const double PI = acos(-1.0);
const double eps = 1e-6;
const ll   mod = 1e9 + 7;
const int  N = 2e5 + 5;

int t, n, m;
char s[110][110];
int mp[110][110];
int x1[N], y1[N], x2[N], y2[N], x3[N], y3[N];

signed main()
{
    
    
    IOS;

    cin >> t;
    while(t --){
    
    
        cin >> n >> m;
        for(int i = 0; i < n; i ++)
            cin >> s[i];
        for(int i = 1; i <= n; i ++)
            for(int j = 1; j <= m; j ++)
                mp[i][j] = s[i-1][j-1]-'0';

        int cnt = 0;    //先把前n-1行的1都处理了
        for(int i = 1; i < n; i ++){
    
    
            for(int j = 1; j <= m; j ++){
    
    
                if(mp[i][j]){
    
    
                    mp[i][j] = !mp[i][j];
                    if(j==1){
    
                                                       // 1
                        mp[i+1][j] = !mp[i+1][j];                               // 11
                        mp[i+1][j+1] = !mp[i+1][j+1];
                        x1[++cnt] = i, y1[cnt] = j;
                        x2[cnt] = i+1, y2[cnt] = j; //下
                        x3[cnt] = i+1, y3[cnt] = j+1; //右下
                    }
                    else{
    
    
                        mp[i+1][j] = !mp[i+1][j];
                        mp[i+1][j-1] = !mp[i+1][j-1];
                        x1[++cnt] = i, y1[cnt] = j;
                        x2[cnt] = i+1, y2[cnt] = j; //下                       //  1
                        x3[cnt] = i+1, y3[cnt] = j-1; //左下                   // 11
                    }
//                    //debug
//                    cout << "cnt:" << cnt << endl;
//                    for(int k = 1; k <= n; k ++){
    
    
//                         for(int l = 1; l <= m; l ++)
//                              cout << mp[k][l];
//                         cout <<endl;
//                    }
                }
            }
        }
        //再来处理最后一行,没次都两个两个考虑(放在2*2矩阵中)
        for(int j = 1; j <= m; j ++){
    
    
            if(mp[n][j]){
    
    //如果遍历最后一行时遇到了1
                if(j<m){
    
     //且它不是最后一个
                    if(mp[n][j+1]){
    
    
                        x1[++cnt] = n, y1[cnt] = j; //自
                        x2[cnt] = n-1, y2[cnt] = j;  //上                     // 00
                        x3[cnt] = n-1, y3[cnt] = j+1;  //右上                 // 11

                        x1[++cnt] = n-1, y1[cnt] = j; //上
                        x2[cnt] = n-1, y2[cnt] = j+1;  //右上
                        x3[cnt] = n, y3[cnt] = j+1;  //右

                        j ++;
                    }
                    else{
    
    
                        x1[++cnt] = n, y1[cnt] = j; //自
                        x2[cnt] = n-1, y2[cnt] = j;  //上
                        x3[cnt] = n, y3[cnt] = j+1;  //右
                                                                              // 00
                        x1[++cnt] = n, y1[cnt] = j; //自                      // 10
                        x2[cnt] = n-1, y2[cnt] = j;  //上
                        x3[cnt] = n-1, y3[cnt] = j+1;  //右上

                        x1[++cnt] = n, y1[cnt] = j; //自
                        x2[cnt] = n, y2[cnt] = j+1;  //右
                        x3[cnt] = n-1, y3[cnt] = j+1;  //右上

                    }
                }
                else{
    
    
                    x1[++cnt] = n, y1[cnt] = j; //自
                    x2[cnt] = n, y2[cnt] = j-1;  //左
                    x3[cnt] = n-1, y3[cnt] = j;  //上

                                                                          // 00
                    x1[++cnt] = n, y1[cnt] = j; //自                      // 01
                    x2[cnt] = n-1, y2[cnt] = j;  //上
                    x3[cnt] = n-1, y3[cnt] = j-1;  //左上


                    x1[++cnt] = n, y1[cnt] = j; //自
                    x2[cnt] = n, y2[cnt] = j-1;  //左
                    x3[cnt] = n-1, y3[cnt] = j-1;  //左上
                }
            }
        }
        cout << cnt << endl;
        for(int i = 1; i <= cnt; i ++)
            cout << x1[i] << " " << y1[i] << " " << x2[i] << " " << y2[i] << " " << x3[i] << " " << y3[i] <<endl;
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/Satur9/article/details/109783437