解いた問題

5/08/2013

SRM498 Div1 Medium

450

マークのある地点までの距離をが等しい箇所を数えてしまって良い。
同じ地点が F 箇所ある場合、ただの並び替えなので F 階乗パターン。


  1. int dist(pair<intint> a, pair<intint> b)  
  2. {  
  3.   return max(abs(a.first - b.first), abs(a.second - b.second));  
  4. }  
  5.   
  6. class FoxStones {  
  7. public:  
  8.   int getCount(int N, int M, vector <int> sj, vector <int> si)  
  9.   {  
  10.     swap(N, M);  
  11.     map< vector<int>, int > cnt;  
  12.     vector< pair<intint> > marked;  
  13.     for (int k = 0; k < si.size(); ++k) {  
  14.       marked.push_back(make_pair(si[k] - 1, sj[k] - 1));  
  15.     }  
  16.     sort(marked.begin(), marked.end());  
  17.   
  18.     for (int i = 0; i < N; ++i) {  
  19.       for (int j = 0; j < M; ++j) {  
  20.         if (binary_search(marked.begin(), marked.end(), make_pair(i, j))) continue;  
  21.         vector<int> u;  
  22.         for (int k = 0; k < marked.size(); ++k) {  
  23.           u.push_back(dist(make_pair(i, j), marked[k]));  
  24.         }  
  25.         ++cnt[u];  
  26.       }  
  27.     }  
  28.   
  29.     const lli mod = 1000000009;  
  30.     const int F = 200 * 200 + 10;  
  31.     lli fact[F];  
  32.     fact[0] = 1;  
  33.     for (lli i = 1; i < F; ++i) {  
  34.       fact[i] = fact[i - 1] * i;  
  35.       fact[i] %= mod;  
  36.     }  
  37.     lli ret = 1;  
  38.     each (i, cnt) {  
  39.       ret *= fact[i->second];  
  40.       ret %= mod;  
  41.     }  
  42.     return ret;  
  43.   }  
  44. }