SPOJ : ABCDEF
問題概要
集合Sが与えられる。要素数N(<100)、要素は[-30000,30000]に含まれる。a,b,c,d,e,f in S、d != 0で、(a*b+c)/d - e = fを満たす組がいくつあるか求める問題。
考えたこと
- 一目は半分全列挙。
- a*b+cの組み合わせを全部列挙して、d*(e+f), d!=0の組み合わせも列挙して、掛け合わせて足せば良い。
- mapを使って実装するもTLE。
- equal_range + distanceを使って実装しなおしたらギリギリ間に合った。
acceptされたコード
#include <cstdio> #include <vector> #include <algorithm> using namespace std; const int MAX_N = 100; int N; int xs[MAX_N]; int solve(){ vector<int> left, right; left.reserve(N*N*N); right.reserve(N*N*N); for(int i=0; i<N; i++){ for(int j=0; j<N; j++){ for(int k=0; k<N; k++){ left.push_back(xs[i] * xs[j] + xs[k]); } } } for(int i=0; i<N; i++)if(xs[i]){ for(int j=0; j<N; j++){ for(int k=0; k<N; k++){ right.push_back( xs[i] * (xs[j] + xs[k]) ); } } } sort(left.begin(), left.end()); sort(right.begin(), right.end()); vector<int> idx = left; idx.erase(unique(idx.begin(), idx.end()), idx.end()); int ans = 0; for(int i=0, M=idx.size(); i<M; i++){ pair<vector<int>::iterator, vector<int>::iterator> L = equal_range(left.begin(), left.end(), idx[i]), R = equal_range(right.begin(), right.end(), idx[i]); ans += distance(L.first, L.second) * distance(R.first, R.second); } return ans; } int main(){ scanf("%d",&N); for(int i=0; i<N; i++){ scanf("%d", xs+i); } printf("%d\n", solve()); return 0; }