TopCoder SRM 399 Div1 Easy AvoidingProduct
問題
整数nが与えられる。自然数x,y,zを、
n-x*y*z | が最小になるようかつ、x,y,zがa[]の要素のどれとも一致しないように選べ。 |
ただし、そのようなx,y,zの組が複数ある場合、
xが最小になるように、それも複数ある場合yが最小になるように、それも複数ある場合zが最小になるように選べ。
制約条件
n≦1000
aの要素の数≦1000
a[i]≦1000
方針
xとyを決め打ちすると、最適なzは一つか二つにしぼれる。
zが、a[]の要素と一致し続ける間+1し続けるor-1しつづければ、
そのx,yに対する最適なzが求まる。
これをx,yについてそれぞれ1050くらいまで回せばよい。
ソースコード
bool ng[1100]; int ax,ay,az,d; void ck(int n,int x,int y,int z){ int cd=abs(n-x*y*z); if(cd<d||cd==d&&(x<ax||x==ax&&y<ay||x==ax&&y==ay&&z<az)) d=cd, ax=x, ay=y, az=z; } class AvoidingProduct { public: vector <int> getTriple(vector <int> a, int n) { memset(ng,0,sizeof(ng)); rep(i,a.size())ng[a[i]]=1; d=inf; for(int x=1;x<=1050;x++)for(int y=1;y<=1050;y++){ if(ng[x]||ng[y])continue; int tz=n/(x*y), z; for(z=tz+1;ng[z];z++); ck(n,x,y,z); for(z=tz;z>0&&ng[z];z--); if(z>0)ck(n,x,y,z); } vi ans; ans.pb(ax); ans.pb(ay); ans.pb(az); return ans; } };