码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 1300D - Aerodynamic

时间:2020-02-10 10:06:35      阅读:72      评论:0      收藏:0      [点我收藏+]

标签:col   ORC   思路   its   mes   force   name   ||   amp   

题目大意:

***证明给定的图形是中心对称图形

点会按照逆时针顺序给出

x和y都是整数

 

解题思路:

已经按照逆时针顺序给出,那判断就很容易了

首先,中心对称图形必须是偶数个点,所以n为奇数直接输出NO

然后,输入n个点,根据中心对称图形的性质,又因为点按照逆时针给出,可得

第1个点和第n/2+1个点

第2个点和第n/2+2个点

第3个点和第n/2+3个点

...

第n/2个点和第n个点

这些两点组合它们的线段会同时交于一点,且这个点也是它们线段的中点

根据这个性质,先记录下第1个点和第n/2+1个点组成线段的中点,就能知道这整个图形的中点(cx,cy)

接下来最多只需要再判断n/2-1组点对就能得出判断结果了

为了防止取中点时/2的误差,所以点要用double储存

正常情况下对于double计算精度问题需要用eps判断两点是否相等,但是由于这题给定的点是整数,/2后最坏情况只能拿到个.5的浮点部分,所以二进制储存是精确的,不需要加eps

代码1(717ms):

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 double x[300050],y[300050];
 4 int main(){
 5     ios::sync_with_stdio(0);
 6     cin.tie(0);cout.tie(0);
 7     int n,i,j;
 8     double cx,cy,dx,dy;
 9     cin>>n;
10     if(n&1){
11         cout<<"NO\n";
12         return 0;
13     }
14     for(i=1;i<=n;i++)
15         cin>>x[i]>>y[i];
16     cx=(x[1]+x[n/2+1])/2.0;
17     cy=(y[1]+y[n/2+1])/2.0;
18     for(i=2,j=n/2+2;j<=n;i++,j++){
19         dx=(x[i]+x[j])/2.0;
20         dy=(y[i]+y[j])/2.0;
21         if(cx!=dx||cy!=dy){
22             cout<<"NO\n";
23             return 0;
24         }
25     }
26     cout<<"YES\n";
27     
28     return 0;
29 }

 

发现这样耗时很大,所以要对计算进行优化

首先可以发现,所有计算中点的式子都有一个/2

如果把所有的/2都去掉,对答案的判断是不会变的

所以double此时也可以改成int了(两种类型计算方式不同时间差别很大)

因为点的最大值只有1e9,相加最大2e9,不会超出int范围,所以不需要开long long

然后,从读入入手,可以先读n/2+1个点,剩下的n/2-1个点边读入边判断(减少这中间的耗时,虽然也差不了多少)

最后,就可以拿到一份看起来更清爽的代码啦

代码2(109ms):

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int x[300050],y[300050];
 4 int main(){
 5     ios::sync_with_stdio(0);
 6     cin.tie(0);cout.tie(0);
 7     int n,i,j,cx2,cy2;
 8     cin>>n;
 9     if(n&1){
10         cout<<"NO\n";
11         return 0;
12     }
13     for(i=1;i<=n/2;i++)
14         cin>>x[i]>>y[i];
15     cin>>x[n/2+1]>>y[n/2+1];
16     cx2=x[1]+x[n/2+1];
17     cy2=y[1]+y[n/2+1];
18     for(i=2,j=n/2+2;j<=n;i++,j++){
19         cin>>x[j]>>y[j];
20         if(x[i]+x[j]!=cx2||y[i]+y[j]!=cy2){
21             cout<<"NO\n";
22             return 0;
23         }
24     }
25     cout<<"YES\n";
26     
27     return 0;
28 }

 

Codeforces 1300D - Aerodynamic

标签:col   ORC   思路   its   mes   force   name   ||   amp   

原文地址:https://www.cnblogs.com/stelayuri/p/12289665.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!