Tokitsukaze and Meeting
题目来源
https://codeforces.com/problemset/problem/1677/B
题目
输入输出样例
解题思路
这应该是一道思维题。题目中求每一步,有多少行和多少列含数字"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行的计数有一点dp的思想。