其他分享
首页 > 其他分享> > B. Tokitsukaze and Meeting_思维

B. Tokitsukaze and Meeting_思维

作者:互联网

B. Tokitsukaze and Meeting_思维

题目大意:

n*m的座位。班级里有0有1,给01串表示大家进入班级就坐的次序,每一时刻进一个人。每个人都会坐在(1,1)座位,其他所有人右移一位。一行或一列在其中有1的情况下被认为是好的。现在要求出对于每一个时刻,好行和好列的和。

思路和代码:

很好的思维题。窝觉得比较难。

首先比较好考虑的是,行列分开计算。

考虑行

resrow[i]表示第i个人进来时行的答案。

对于行来说,第二行到最后一行我们都是算过的。也就是说,我们可以有以下式子:resrow[i]=resrow[i-m]+{第一行是否是好行}

对于第一行是否good,我们只需要维护第一行的1的数量即可。

考虑列

rescol[i]表示第i个人进来时列的答案。

对于列来说,第i层的[2,m]列就是第i-1层的[1,m-1]列。

而且观察每一列的数值的下标可以发现,每一列的所有下标对m取模的值都是相同的。所以我们就可以维护一个col[j%m]来维护某一列是否有1。

void solve(){
	cin >> n >> m ;
	
	string s ; cin >> s ;
	s = " " + s ;
	
	vct<int> rescol(n * m + 1 , 0) ;
	vct<int> resrow(n * m + 1 , 0) ;
	int row1 = 0 ;//维护第一行1的数量 
	vct<int> col(m + 1 , 0) ;//维护所有的m列的1数量 
	
	rep(i , 1 , n * m){
		//resrow
		if(i <= m){
			resrow[i] = resrow[i - 1] ;
			if(s[i] == '1'){
				if(!row1) resrow[i] ++ ;
				row1 ++ ;
			}
			continue ;
		}
		if(s[i - m] == '1') row1 -- ;
		//第一行的最后一个1被顶到第二行去了
		row1 += s[i] == '1' ;
		resrow[i] = resrow[i - m] + (row1 > 0) ;
	}
	
	rep(i , 1 , n * m){
		//rescol
		rescol[i] = rescol[i - 1] ;
		if(s[i] == '1'){
			if(!col[i % m]) rescol[i] ++ ;
			col[i % m] ++ ;
		}
	}
	rep(i , 1 , n * m)
	cout << rescol[i] + resrow[i] << " \n"[i == n * m] ;
	 
}//code_by_tyrii 

小结:

很好的思维题,做题的时候不能懒,要多做样例多找规律。

想不明白的时候就多写写样例。

标签:思维,rescol,第一行,rep,resrow,Tokitsukaze,一列,Meeting,col
来源: https://www.cnblogs.com/tyriis/p/16266143.html