題目來源: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;
}