Tokitsukaze and Meeting

题目来源

https://codeforces.com/problemset/problem/1677/B

题目

image

输入输出样例

image

解题思路

这应该是一道思维题。题目中求每一步,有多少行和多少列含数字"1"。按照题目放置数字的方式,先对列考虑,序号对m取模之后相同的数字一定在同一列,因此每一步将数字的序号对m取模记录计数,得出每一步含1列的数目;再考虑行,每一步相当于m步之前再塞进去这一行,所以这时含1行的数目就相当于,m步之前含1行的数目加上这一行,如果这一行含1就加1,否则不变,用一个变量维护一下最后m个数是否含1。

代码

点击查看代码
#include<bits/stdc++.h>
using namespace std;

#define ll long long

const int maxn = 2e6+7;
int n,m;
string s;
int col[maxn];
int row[maxn];
bool colh[maxn];

signed main()
{
    int t;cin >> t;
    while(t--){
        cin >> n >> m;
        cin >> s;
        for(int i=0;i<n*m;++i)
            row[i] = 0;
        for(int j=0;j<n*m;++j)
            colh[j] = col[j] = 0;

        //column
        int k = 0,num = 0;
        for(char c : s){
            if(c=='1'){
                if(!colh[k%m]){
                    colh[k%m] = 1;
                    num++;
                }
            }
            col[k] = num;
            ++k;
        }

        //row
        k = 0;num=0;
        for(int i=0;i<m*n;++i){
            if(k<m){
                if(s[i]=='1'){
                    ++num;
                    row[k] = 1;
                }
                else{
                    if(num) row[k] = 1;
                    else row[k] = 0;
                }
            }
            else{
                if(s[i-m]=='1') num--;
                if(s[i]=='1') num++;
                if(num){
                    row[k] = row[k-m] + 1;
                }
                else row[k] = row[k-m];
            }
            ++k;
        }

        //cout
        cout << col[0] + row[0];
        for(int i=1;i<n*m;++i)
        {
            cout << " " << col[i] + row[i];
        }
        cout << endl;
    }

    return 0;
}

反思

  1. 这个题一开始没有想到行和列分开考虑。。行和列是独立的两种判断条件,显然分开考虑更加简单一点。
  2. 含1行的计数有一点dp的思想。
posted @ 2022-05-14 15:58  HIVM  阅读(20)  评论(0编辑  收藏  举报