CSU 1896: Symmetry(对称点集)
来源:互联网 发布:python 多线程 返回值 编辑:程序博客网 时间:2024/06/05 20:06
题目:
Description
We call a figure made of points is left-right symmetric as it is possible to fold the sheet of paper along a vertical line and to cut the figure into two identical halves.For example, if a figure exists five points, which respectively are (-2,5),(0,0),(2,3),(4,0),(6,5). Then we can find a vertical line x = 2 to satisfy this condition. But in another figure which are (0,0),(2,0),(2,2),(4,2), we can not find a vertical line to make this figure left-right symmetric.Write a program that determines whether a figure, drawn with dots, is left-right symmetric or not. The dots are all distinct.
Input
The input consists of T test cases. The number of test cases T is given in the first line of the input file. The first line of each test case contains an integer N, where N (1 <=N <= 1, 000) is the number of dots in a figure. Each of the following N lines contains the x-coordinate and y-coordinate of a dot. Both x-coordinates and y-coordinates are integers between −10, 000 and 10, 000, both inclusive.
Output
Print exactly one line for each test case. The line should contain 'YES' if the figure is left-right symmetric,and 'NO', otherwise.
Sample Input
35-2 50 06 54 02 342 30 44 00 045 146 105 106 14
Sample Output
YESNOYES
这个题目是说,给一个整点集,判断是不是左右对称的。
要分2步进行,第一步找到唯一可能的对称轴的位置,第二步是判断点集是不是关于这条直线对称的。
第一步我是找最中间的若干个点,第二步我是把所有不在对称轴上面的点映射到一个整数,使得对称的点映射到一样的整数,不对称的点几乎不会映射到一样的整数,最后求出所有整数的异或,是0就对称,不是0就不对称。
我在比赛时提交的代码:
#include<iostream>#include<algorithm>using namespace std;int kx1,kx2;struct node{int x,y;};bool cmp(node n1,node n2){return n1.x<n2.x;}int f(node nodd,int kx){if(nodd.x*2<kx)return (kx-nodd.x*2)%123*nodd.y;return (nodd.x*2-kx)%123*nodd.y;}int main(){int T,N,ans1,ans2;node nod[1000];cin>>T;while(T--){cin>>N;for(int i=0;i<N;i++)cin>>nod[i].x>>nod[i].y;sort(nod,nod+N,cmp);kx1=nod[N/2].x*2;kx2=nod[N/2].x+nod[(N-1)/2].x;ans1=ans2=0;for(int i=0;i<N;i++){ans2=ans2^f(nod[i],kx2);if(nod[i].x==kx1)continue;ans1=ans1^f(nod[i],kx1);}if(ans1==0||ans2==0)cout<<"YES\n";else cout<<"NO\n";}return 0;}
实际上求对称轴还有更好的方法,不用最中间的点,用最左边和最右边的点。
第二步也不需要映射到整数,直接把点集存2份,一份从左往右排序,一份从右往左排序,然后一一比较是否对称即可。
新代码:
#include<iostream>#include<algorithm>using namespace std;int T, N, kx;struct node{int x, y;};node nod1[1000], nod2[1000];bool cmp1(node n1, node n2){if (n1.x == n2.x)return n1.y < n2.y;return n1.x<n2.x;}bool cmp2(node n1, node n2){if (n1.x == n2.x)return n1.y < n2.y;return n1.x>n2.x;}bool ok(){for (int i = 0; i < N; i++){if (nod1[i].y != nod2[i].y)return false;if (nod1[i].x + nod2[i].x != kx)return false;}return true;}int main(){int left, right;cin >> T;while (T--){cin >> N;left = 10000, right = -10000;for (int i = 0; i < N; i++){cin >> nod1[i].x >> nod1[i].y;nod2[i].x = nod1[i].x, nod2[i].y = nod1[i].y;if (left>nod1[i].x)left = nod1[i].x;if (right < nod1[i].x)right = nod1[i].x;}kx = left + right;sort(nod1, nod1 + N, cmp1);sort(nod2, nod2 + N, cmp2);if (ok())cout << "YES\n";else cout << "NO\n";}return 0;}
- CSU 1896: Symmetry(对称点集)
- Symmetry CSU
- FZU 2035 Axial symmetry(判断多边形是否对称)
- Fast Radial Symmetry Transform/快速径向对称变换(代码)
- 最优对称路径 CSU
- Symmetry
- Symmetry
- Fast Radial Symmetry Transform/快速径向对称变换
- Fast Radial Symmetry Transform/快速径向对称变换
- 项目三--枚举(对称点)
- Symmetry UVa 1595(水题)
- Symmetry(对称轴)UVA 1595
- CSU 1503: 点到圆弧的距离(计算几何)
- 枚举题目--对称点!
- 枚举法对称点
- fzu 2035 Axial symmetry(枚举+几何)
- FZU - 2035 Axial symmetry(几何+暴力)
- UVa 1595 - Symmetry(对比查找)
- shareSDK使用
- HTML5基础加强css样式篇(伸缩容器属性:flex-direction, flex-wrap,flex-flow,align-items,align-content)(五十三)
- 【LEET-CODE】27. Remove Element
- 通过LoadLibrary() 与 GetProcAddress()获得Dll内的函数
- iOS js和OC方法交互
- CSU 1896: Symmetry(对称点集)
- H.264编码下直播视频添加水印的优化
- Mac版R语言(四)网络数据自动获取
- Java中的23种设计模式
- 键盘Keycode对照表
- 程序员什么时候该考虑辞职?
- 贪心(ZOJ 3778,Talented Chef)
- WORD2010/WPS使用快捷键
- 第五次c++上机实验报告