Codeforces 1299B/1300D - Aerodynamic
题目大意:
给定一个图形S,让这个图形任意平移,但是要保证原点(0,0)一直在它的内部或者边上
最后把它能移动到的所有位置进行拼合可以得到一个图形T
问图形S与图形T是否相似
点会按照逆时针顺序给出
x和y都是整数
图1:图示正三角形平移后拼合可以得到一个正六边形

图2:斜正方形平移后拼合可以得到一个大的斜正方形

解题思路:
证:
首先能得到的结论是,不论给定的是什么图形,让他平移后得到的图形T绝对是一个中心对称图形(这个草稿纸上证明下吧,或者下面也会有证明)
所以要想让某个图形与一个中心对称图形对称,那么这个图形也必须是中心对称图形
那么就需要证明对于中心对称图形是否存在某种限制不符合题意
可以由中心对称图形的性质得到,假设图形上某条边为a,与这条边呈中心对称的另外一条边为b
那么一定会有|a|=|b|,且a//b
在根据题意进行平移之后,对应的边将会是当前边长+对称边边长和
又因为|a|=|b|,所以对应边会变成原来的两倍长,即a对应的边边长为|a|+|b|=2|a|,b对应边的边长为|b|+|a|=2|b|
即,中心对称图形进行平移后得到的图形T是原本的图形扩大2倍的结果,任何中心对称图形都满足题意
只要给定的图形S不是中心对称图形,首先,肯定存在一条边没有他的中心对称边(一定存在a找不到a//b的b)
那么当前位置平移后将会得到边长为|a|+0,对称的位置的边(在S中不存在的但是又要和a平行的那个位置,在T中存在)对应将会得到边长为0+|a|的边
所以可以证明得到图形T一定是中心对称图形
以不是中心对称的四边形为例,易得到上述结论:


如图所示的是,因为a和c没有与其平行的对应边,所以会单独成两个对应边,长度为自身
因为b与d互为平行边,所以可以凑成两个长为b+d的对应边
解:
已经按照逆时针顺序给出,那判断就很容易了
首先,中心对称图形必须是偶数个点,所以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):
#include<bits/stdc++.h>
using namespace std;
double x[],y[];
int main(){
ios::sync_with_stdio();
cin.tie();cout.tie();
int n,i,j;
double cx,cy,dx,dy;
cin>>n;
if(n&){
cout<<"NO\n";
return ;
}
for(i=;i<=n;i++)
cin>>x[i]>>y[i];
cx=(x[]+x[n/+])/2.0;
cy=(y[]+y[n/+])/2.0;
for(i=,j=n/+;j<=n;i++,j++){
dx=(x[i]+x[j])/2.0;
dy=(y[i]+y[j])/2.0;
if(cx!=dx||cy!=dy){
cout<<"NO\n";
return ;
}
}
cout<<"YES\n"; return ;
}
发现这样耗时很大,所以要对计算进行优化
首先可以发现,所有计算中点的式子都有一个/2
如果把所有的/2都去掉,对答案的判断是不会变的
所以double此时也可以改成int了(两种类型计算方式不同时间差别很大)
因为点的最大值只有1e9,相加最大2e9,不会超出int范围,所以不需要开long long
然后,从读入入手,可以先读n/2+1个点,剩下的n/2-1个点边读入边判断(减少这中间的耗时,虽然也差不了多少)
代码2(109ms):
#include<bits/stdc++.h>
using namespace std;
int x[],y[];
int main(){
ios::sync_with_stdio();
cin.tie();cout.tie();
int n,i,j,cx2,cy2;
cin>>n;
if(n&){
cout<<"NO\n";
return ;
}
for(i=;i<=n/;i++)
cin>>x[i]>>y[i];
cin>>x[n/+]>>y[n/+];
cx2=x[]+x[n/+];
cy2=y[]+y[n/+];
for(i=,j=n/+;j<=n;i++,j++){
cin>>x[j]>>y[j];
if(x[i]+x[j]!=cx2||y[i]+y[j]!=cy2){
cout<<"NO\n";
return ;
}
}
cout<<"YES\n"; return ;
}
Codeforces 1299B/1300D - Aerodynamic的更多相关文章
- Codeforces Round #618 (Div. 2)
题库链接 https://codeforces.ml/contest/1300 A. Non-zero 一个数组,每次操作可以给某个数加1,让这个数组的积和和不为0的最小操作数 显然如果有0的话,必须 ...
- Codeforces题解集 1.0
记录 Codeforces 2019年12月19日到 2020年2月12日 的部分比赛题 Educational Codeforces Round 82 (Rated for Div. 2) D Fi ...
- python爬虫学习(5) —— 扒一下codeforces题面
上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...
- 【Codeforces 738D】Sea Battle(贪心)
http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...
- 【Codeforces 738C】Road to Cinema
http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...
- 【Codeforces 738A】Interview with Oleg
http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...
- CodeForces - 662A Gambling Nim
http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...
- CodeForces - 274B Zero Tree
http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...
- CodeForces - 261B Maxim and Restaurant
http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...
随机推荐
- 学习Linux系统永远都不晚
作为一名机械专业毕业的学生,两年的工作经历实实在在地教会了我如何认清现实,让当初那个对机械行业无比憧憬的少年明白了自己选择的路有多艰难.由于我的父母都是工人,所以我比其他同龄人能更早地接触到工业的魅力 ...
- 你必须知道的.Net 8.2.2 本质分析
1 .Equals 静态方法 Equals 静态方法实现了对两个对象的相等性判别,其在 System.Object 类型中实现过程可以表 示为: public static bool Equals ...
- 第1课 VMware的NSX全面落地软件定义网络SDN
SDN的定义: 即软件定义网络(Software Defined Network)的缩写,它是一种基于网络架构的创新,一种在已存在物理传输网络之上的抽象形态,它是一种体系结构,它是众多网络虚拟化技术中 ...
- IDEA开发spring boot应用时 application.yml 或 application.properties 自定义属性提示
在使用spring boot开发过程中,经常会定义一些应用自己的属性,直接写到application配置文件中使用@Value注解进行使用,这样使用也没有什么问题.不过我认为更优雅的方式是定义自己的属 ...
- 020、MySQL创建一个存储过程,显示存储过程,调用存储过程,删除存储过程
一.我们创建一个MySQL储存过程,在SQL代码区写入以下内容,并执行就可以了 #编写一个存储过程 CREATE PROCEDURE ShowDate ( ) BEGIN #输出当前时间 SELECT ...
- 剑指offer自学系列(四)
题目描述: 输入一个正整数数组,把数组里面所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个,例如输入数组{3,32,321},输出的最小数字为321323 题目分析: 如果采用穷举法,把 ...
- OpenMandriva或将放弃32位的支持
导读 除了Ubuntu计划在其19.10发行版中删除32位包之外,OpenMandriva开发团队也是另一个备受关注的Linux发行版起草计划,以取消对32位包的支持. OpenMandriva计划在 ...
- GNS3 模拟icmp禁止不可达
R1 : conf t int f0/0 no shutdown ip add 192.168.1.1 255.255.255.0 no ip routing end R2 f0/0: conf t ...
- Spring Boot2(007):关于Spring beans、依赖注入 和 @SpringBootApplication 注解
一.关于Spring beans 和 依赖注入(Dependency Injection) spring boot 和 Spring 全家桶无缝衔接,开发过程中可以很轻松地使用 Spring 全家桶的 ...
- cf 498 B. Name That Tune
不会不会,,,%%http://hzwer.com/5813.html #include<cstdio> #include<iostream> #include<algo ...