公式
D - Counting Ls 解説 by physics0523
ひとつ三つ組の例をとって観察してみましょう。
......o
.......
.o....o
「マスのうち、丁度 \(2\) つが同じ行にある」「マスのうち、丁度 \(2\) つが同じ列にある」という条件から、このどちらにも当てはまるマスが丁度 \(1\) つあることが分かります。例の中では、右下の o
がそれにあたります。
このマス \(s\) を決め打つ (全探索する) ことを考えましょう。残りの \(2\) マスはどのように選ぶことができるでしょうか?
結論としては、以下のような選び方をすることになります。
- \(s\) と同じ行にある \(s\) 以外の
o
マスを丁度 \(1\) つ選ぶ - \(s\) と同じ列にある \(s\) 以外の
o
マスを丁度 \(1\) つ選ぶ
このような選び方の数は、 ( \(s\) と同じ行にある \(s\) 以外の o
マスの個数 ) \(\times\) ( \(s\) と同じ列にある \(s\) 以外の o
マスの個数 ) で求めることができます。
これは、あらかじめ各行各列の o
マスの数を数えておくことで高速に求めることができます。
実装例 (C++):
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
vector<string> s(n);
vector<long long> bi(n,0),bj(n,0);
for(int i=0;i<n;i++){
cin >> s[i];
for(int j=0;j<n;j++){
if(s[i][j]=='o'){
bi[i]++;
bj[j]++;
}
}
}
long long res=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(s[i][j]=='o'){
res+=(bi[i]-1)*(bj[j]-1);
}
}
}
cout << res << "\n";
return 0;
}
投稿日時:
最終更新: