【題解】勇者比太郎

題目來源:loj
在這裏插入圖片描述

思路:

題目的意思就是先找到一個J,然後往這一行的後面找O的個數cnto,往這一列的下面找I的個數cnti,那麼這個J對應的方案個數就是cnt0*cnti,總方案個數就是總的J對應的方案個數

怎麼求這個J下面及後面的O和J的個數?可以用兩個後綴和數組來找
尋找J的時間複雜度爲O(h*w),查找時間只需要O(1),不會超時

後綴數組是什麼?emmm…
那就前綴數組吧

code:

#include<bits/stdc++.h>
using namespace std;
const int N=3010;
long long n,m,O[N][N],I[N][N],anss,cnto,cnti;
//O[i][j]:前i行j列總共有多少個O
//I[i][j]:前i行j列總共有多少個I 
char a[N][N];
int main()
{
	scanf("%lld%lld",&n,&m);
	for (int i=1;i<=n;i++)
	  for (int j=1;j<=m;j++) 
	  {
	  	  cin>>a[i][j];
	  	  O[i][j]+=O[i][j-1]+O[i-1][j]+(a[i][j]=='O')-O[i-1][j-1];//O的前綴和 
		  I[i][j]+=I[i][j-1]+I[i-1][j]+(a[i][j]=='I')-I[i-1][j-1];//I的前綴和 
	  }
	  
	for (int i=1;i<=n;i++)
	  for (int j=1;j<=m;j++)
	  {
	  	if (a[i][j]=='J')  //找到J了 
	  	{
	  		cnto=O[i][m]-O[i][j-1]-O[i-1][m]+O[i-1][j-1]; //J的下面有多少個O 
	  		cnti=I[n][j]-I[n][j-1]-I[i-1][j]+I[i-1][j-1];//J的右邊有多少個I 
	  	    anss+=cnto*cnti;//更新方案數 
	  	}
	  }
	printf("%lld\n",anss);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章