Skip to content

Commit 9dffe47

Browse files
authoredApr 20, 2019
math, FFT
1 parent ac1b8da commit 9dffe47

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed
 

‎HackerRank/Best spot_butterfly.cpp

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//math, FFT
2+
//https://www.hackerrank.com/contests/w6/challenges/best-spot/editorial
3+
#include <stdio.h>
4+
#include <math.h>
5+
#include <algorithm>
6+
#include <vector>
7+
#include <complex>
8+
#define cpd complex<double>
9+
using namespace std;
10+
const double PI = acos(-1);
11+
int rearr[1 << 19];
12+
int R, C,H,W;
13+
int sqx[500][500],xy[500][500];
14+
int rev(int n, int k) {
15+
int r = 0;
16+
while (k--) {
17+
r += r + (n & 1);
18+
n >>= 1;
19+
}
20+
return r;
21+
}
22+
void FFT(vector<cpd > &A, bool inv = 0) {
23+
for (int i = 0; i < A.size(); ++i)
24+
if (rearr[i]) swap(A[i], A[rearr[i]]);
25+
int half = 1;
26+
for (int step = 2; step <= A.size(); step += step) {
27+
double theta = (PI + PI) / step;
28+
if (inv) theta = -theta;
29+
cpd w(cos(theta), sin(theta));
30+
for (int i = 0; i < A.size(); i += step) {
31+
cpd x = 1;
32+
for (int j = 0; j < half; ++j) {
33+
cpd odd = A[i + j + half]*x;
34+
A[i + j + half] = A[i + j] - odd;
35+
A[i + j] += odd;
36+
x *= w;
37+
}
38+
}
39+
half = step;
40+
}
41+
for (int i = 0; inv && i < A.size(); ++i) A[i] /= A.size();
42+
}
43+
int main() {
44+
int i, j,RC,p=1;
45+
int k = 0;
46+
int sqy = 0;
47+
for (scanf("%d%d", &R, &C), RC = R * C; p < RC + RC; p += p) ++k;
48+
for (i = 0; i < p; ++i) {
49+
j = rev(i, k);
50+
if (i < j) rearr[i] = j;
51+
}
52+
vector<cpd > h(p), ps(p);
53+
int ix = 0;
54+
for (i = 0; i < R; ++i,ix+=C) {
55+
for (j = 0; j < C; ++j) {//range sum
56+
scanf("%d",sqx[i]+j);
57+
h[ix + j] = h[ix + j + RC] = sqx[i][j];
58+
sqx[i][j] *= sqx[i][j];
59+
if (i > 0) sqx[i][j] += sqx[i - 1][j];
60+
if (j > 0) sqx[i][j] += sqx[i][j - 1];
61+
if (i > 0 && j > 0) sqx[i][j] -= sqx[i - 1][j - 1];
62+
}
63+
}
64+
for (scanf("%d%d",&H,&W),i = 0,ix=RC; i < H; ++i,ix-=C) {
65+
for(j = 0; j < W; ++j) {
66+
int height; scanf("%d",&height);
67+
ps[ix - j - 1] = height;
68+
sqy += height * height;
69+
}
70+
}
71+
FFT(h); FFT(ps);
72+
for (i = 0; i < p; ++i) h[i] *= ps[i];
73+
FFT(h, 1);
74+
for (ix = RC-1, i = 0; i < R; ++i) {
75+
for (j = 0; j <C; ++j, ++ix) {
76+
double coef = h[ix].real();
77+
coef += coef > 0 ? 0.5 : -0.5;
78+
xy[i][j] = coef;
79+
//printf("%d\n",xy[i][j]);
80+
}
81+
}
82+
int ans = -1;
83+
int r, c;
84+
for (i = 0; i <= R-H; ++i) {
85+
for(j = 0; j <= C-W; ++j) {
86+
int sum = sqx[i+H-1][j+W-1]+sqy;
87+
if (i > 0) sum -= sqx[i - 1][j + W - 1];
88+
if (j > 0) sum -= sqx[i + H - 1][j - 1];
89+
if (i > 0 && j > 0) sum += sqx[i - 1][j - 1];
90+
sum -= xy[i][j] + xy[i][j];
91+
if (ans<0 || ans>sum) {
92+
ans = sum;
93+
r = i + 1; c = j + 1;
94+
}
95+
}
96+
}
97+
printf("%d\n%d %d",ans,r,c);
98+
99+
return 0;
100+
}

0 commit comments

Comments
 (0)
Please sign in to comment.