CodeForcesGym 100524A Astronomy Problem
Astronomy Problem
Time Limit: 8000ms
Memory Limit: 524288KB
This problem will be judged on CodeForcesGym. Original ID: 100524A64-bit integer IO format: %I64d Java class name: (Any)
解题:暴力搞
$设两个点的坐标分别为(x_1,y_1),(x_2,y_2)且有x_1^2+y_1^2 = a^2,x_2^2+y_2^2=b^2,那么有(x_1-x_2)^2+(y_1-y_2)^2=c^2。$
$于是推出一个错误的公式,a^2+b^2-c^2=2\times (x_1\times x_2+y_1\times y_2),初略的想法是:等式右边是固定的,所以可以根据这个进行排序,左边是不定的$
$可以用左边找右边,可是,可是,WA第7组数据. 因为,你算多了,而且这个等式本身就不对$
$但是,但是,这个错误的等式可以为我们省出不少的点对,只要不满足这个等式的点对,一定不是符合条件的,但是满足这个等式,也有可能不符合条件$
$所以只会找出这些点对,进行一一检验即可$
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int maxn = 3010; 5 struct Point{ 6 LL val,a,b,c; 7 Point(LL val = 0,LL a = 0,LL b = 0,LL c = 0){ 8 this->val = val; 9 this->a = a; 10 this->b = b; 11 this->c = c; 12 } 13 bool operator<(const Point &rhs)const{ 14 return val < rhs.val; 15 } 16 }P[maxn*maxn]; 17 int x[maxn],y[maxn],n,q,tot; 18 LL calc(int a,int b){ 19 LL tmp = (LL)(x[a] - x[b])*(x[a] - x[b]); 20 return tmp + (LL)(y[a] - y[b])*(y[a] - y[b]); 21 } 22 int main(){ 23 freopen("astronomy.in","r",stdin); 24 freopen("astronomy.out","w",stdout); 25 while(~scanf("%d",&n)){ 26 if(!n) break; 27 tot = 0; 28 for(int i = 1; i <= n; ++i){ 29 scanf("%d%d",x + i,y + i); 30 for(int j = 1; j < i; ++j){ 31 LL tmp = ((LL)x[i]*x[j] + (LL)y[i]*y[j])<<1; 32 P[tot++] = Point(tmp,calc(j,0),calc(i,0),calc(i,j)); 33 } 34 } 35 sort(P,P + tot); 36 scanf("%d",&q); 37 while(q--){ 38 LL a,b,c; 39 scanf("%I64d%I64d%I64d",&a,&b,&c); 40 LL tmp = a - c + b; 41 if(n == 1 || tmp&1){ 42 puts("0"); 43 continue; 44 } 45 int low = lower_bound(P,P + tot,Point(tmp,0,0,0)) - P,ret = 0; 46 while(low < tot && P[low].val == tmp){ 47 if(P[low].a == a && P[low].b == b || P[low].a == b && P[low].b == a) ++ret; 48 ++low; 49 } 50 printf("%d\n",ret); 51 } 52 } 53 return 0; 54 } 55 /* 56 4 57 0 2 58 2 0 59 4 0 60 0 -4 61 2 62 4 16 20 63 16 4 20 64 */
然后学习了下某位大神的写法
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const int maxn = 3010; 5 unordered_map<LL,vector<int>>ump; 6 unordered_map<LL,int>ret; 7 map<pair<LL,LL>,vector<pair<LL,int>>>Q; 8 struct Point { 9 LL x,y; 10 Point(LL x = 0,LL y = 0) { 11 this->x = x; 12 this->y = y; 13 } 14 } p[maxn]; 15 LL calc(const Point &a,const Point &b) { 16 LL tmp = (a.x - b.x)*(a.x - b.x); 17 return tmp + (a.y - b.y)*(a.y - b.y); 18 } 19 set<LL>st; 20 int ans[maxn]; 21 int main() { 22 #define NAME "astronomy" 23 freopen(NAME".in","r",stdin); 24 freopen(NAME".out","w",stdout); 25 int n,q; 26 while(~scanf("%d",&n)) { 27 if(!n) break; 28 ump.clear(); 29 Q.clear(); 30 memset(ans,0,sizeof ans); 31 for(int i = 1; i <= n; ++i) { 32 scanf("%I64d%I64d",&p[i].x,&p[i].y); 33 ump[p[i].x*p[i].x+p[i].y*p[i].y].push_back(i); 34 } 35 scanf("%d",&q); 36 for(int i = 0; i < q; ++i){ 37 LL a,b,c; 38 scanf("%I64d%I64d%I64d",&a,&b,&c); 39 Q[make_pair(a,b)].push_back(make_pair(c,i)); 40 } 41 for(auto &it:Q){ 42 st.clear(); 43 for(auto &it2:it.second) st.insert(it2.first); 44 LL a = it.first.first,b = it.first.second; 45 ret.clear(); 46 for(auto &x:ump[a]){ 47 for(auto &y:ump[b]){ 48 if(a == b && x < y) continue; 49 if(x == y) continue; 50 LL d = calc(p[x],p[y]); 51 if(st.find(d) == st.end()) continue; 52 ret[d]++; 53 } 54 } 55 for(auto &v:it.second) 56 ans[v.second] = ret[v.first]; 57 } 58 for(int i = 0; i < q; ++i) 59 printf("%d\n",ans[i]); 60 } 61 return 0; 62 } 63 /* 64 4 65 0 2 66 2 0 67 4 0 68 0 -4 69 2 70 4 16 20 71 16 4 20 72 */
夜空中最亮的星,照亮我前行