标签:style blog http color os io ar for 2014
E 为边数 ,V 为点数,F为面数
那么 F = E + 2 - V(其中包括了一个无限大的面)
这道题被自己的习惯坑了一下#define MAXD 300 + 10 和#define MAXD 310 是不一样的
| 14113235 | 1342 | That Nice Euler Circuit | Accepted | C++ | 0.082 | 2014-08-29 15:12:20 |
自己的代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define INF 1 << 30
#define eps 1e-10
#define Vector Point
#define MAXD 310
/*=============================================*/
int dcmp(double x){
if(fabs(x) < eps)
return 0;
else
return x < 0 ? -1 : 1;
}
struct Point{
double x;
double y;
Point(double a = 0,double b = 0): x(a),y(b) {};
friend bool operator < (Point p,Point q){
if(p.x == q.x)
return p.y < q.y;
else
return p.x < q.x;
}
friend Vector operator + (Point p,Point q){
return Vector(p.x + q.x , p.y + q.y);
}
friend Vector operator - (Point p,Point q){
return Vector(p.x - q.x , p.y - q.y);
}
friend Vector operator * (Point p,double t){
return Vector(p.x * t , p.y * t);
}
friend Vector operator / (Point p,double t){
return Vector(p.x / t , p.y / t);
}
friend bool operator == (Point p,Point q){
return dcmp(p.x - q.x) == 0 && dcmp(p.y - q.y) == 0;
}
};
double Dot(Vector p, Vector q){ //向量点积
return p.x * q.x + p.y * q.y;
}
double Length(Vector p){ //向量长度
return sqrt(p.x * p.x + p.y * p.y);
}
double Angle(Vector p ,Vector q){
return acos( Dot(p, q) /( Length(p) * Length(q) ) );
}
double Cross(Vector p,Vector q){
return p.x * q.y - p.y * q.x;
}
double Area2(Point a,Point b,Point c){
return Cross(a - b , c - b);
}
Vector Rotate(Vector p,double angle){
return Vector(p.x * cos(angle) - p.y * sin(angle), p.x * sin(angle) + p.y * cos(angle));
}
Vector Normal(Vector p){ //求法向量
double L = Length(p);
return Vector( - p.y / L , p.x / L);
}
Point GetLineCross(Point p,Vector v,Point q,Vector w){ //交点
Vector u = p - q;
double t = Cross(w,u) / Cross(v,w);
return p + v * t;
}
double Distance(Point p,Point a,Point b){ //点到射线的距离
Vector v1 = b - a;
Vector v2 = p - a;
return fabs(Cross(v1,v2)) / Length(v1);
}
double Distance2(Point p,Point a,Point b){
if(a == b)
return Length(p - a);
Vector v1 = b - a , v2 = p - a, v3 = p - b;
if(dcmp(Dot(v1,v2)) < 0)
return Length(v2);
else if(dcmp(Dot(v1,v3)) > 0)
return Length(v3);
else
return fabs(Cross(v1,v2))/ Length(v1);
}
Point GetLinePoint(Point p,Point a,Point b){ //点在线上的投影
Vector v = b - a;
return a + v * (Dot(v, p -a ) / Dot(v,v));
}
bool If_Cross(Point a1,Point a2,Point b1,Point b2){ //是否相交
double c1 = Cross(a2 - a1 , b1 - a1) , c2 = Cross(a2 - a1 , b2 - a1),
c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1, a2 - b1);
return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
}
bool If_InLine(Point p,Point a1,Point a2){
return dcmp(Cross(a1 - p , a2 - p)) == 0 && dcmp(Dot(a1 - p , a2 - p)) < 0;
}
Point point[MAXD],V[MAXD * MAXD];
int main(){
int n,Case = 1;
while(scanf("%d",&n) && n){
for(int i = 0 ; i < n ; i++){
scanf("%lf%lf",&point[i].x,&point[i].y);
V[i] = point[i];
}
n--;
int c = n ,e = n ;//分别为点数和线段书
for(int i = 0 ; i < n ; i++){
for(int j = i + 1 ; j < n ; j++){
if(If_Cross(point[i],point[i + 1],point[j],point[j + 1])){
V[c++] = GetLineCross(point[i],point[i + 1] - point[i],point[j],point[j + 1] - point[j]);
}
}
}
sort(V,V + c);
c = unique(V,V + c) - V;//去除重复元素,返回首地址
for(int i = 0 ; i < c ; i++){
for(int j = 0 ; j < n ; j++){
if(If_InLine(V[i],point[j],point[j + 1]))
e++;
}
}
printf("Case %d: There are %d pieces.\n",Case ++ , e + 2 - c);
}
return 0;
}
网上有的代码更清晰,模板也更好,copy一下:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
const double eps = 1e-10;
struct Point
{
double x, y;
Point(double x = 0, double y = 0) : x(x), y(y) { }
bool operator < (const Point& a) const
{
if(a.x != x) return x < a.x;
return y < a.y;
}
};
typedef Point Vector;
Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator - (Point A, Point B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
int dcmp(double x)
{
if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1;
}
bool operator == (const Point& a, const Point &b)
{
return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;
}
double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
double Length(Vector A) { return sqrt(Dot(A, A)); }
double Angle(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); }
double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }
double Area2(Point A, Point B, Point C) { return Cross(B-A, C-A); }
Vector Rotate(Vector A, double rad)
{
return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad) + A.y*cos(rad));
}
Point GetIntersection(Point P, Vector v, Point Q, Vector w)
{
Vector u = P-Q;
double t = Cross(w, u) / Cross(v, w);
return P+v*t;
}
bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2)
{
double c1 = Cross(a2-a1, b1-a1), c2 = Cross(a2-a1, b2-a1);
double c3 = Cross(b2-b1, a1-b1), c4 = Cross(b2-b1, a2-b1);
return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
}
double PolygonArea(Point* p, int n)
{
double area = 0;
for(int i = 1; i < n-1; i++)
area += Cross(p[i]-p[0], p[i+1]-p[0]);
return area;
}
bool OnSegment(Point p, Point a1, Point a2)
{
return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
}
Point read_point()
{
Point A;
scanf("%lf%lf", &A.x, &A.y);
return A;
}
int n;
const int maxn = 310;
Point P[maxn], V[maxn*maxn];
int read_case()
{
scanf("%d", &n);
if(!n) return 0;
for(int i = 0; i < n; i++) P[i] = read_point(), V[i] = P[i];
n--;
return 1;
}
void solve()
{
int v = n, e = n;
for(int i = 0; i < n; i++)
{
for(int j = i+1; j < n; j++)
{
if(SegmentProperIntersection(P[i], P[i+1], P[j], P[j+1]))
{
V[v++] = GetIntersection(P[i], P[i+1]-P[i], P[j], P[j+1]-P[j]); //新增加的点数
}
}
}
sort(V, V+v); //排序
v = unique(V, V+v) - V; //去重
for(int i = 0; i < v; i++)
{
for(int j = 0; j < n; j++) //判断新增加的边数
{
if(OnSegment(V[i], P[j], P[j+1])) e++;
}
}
int ans = e+2-v;
printf("There are %d pieces.\n", ans);
}
int main()
{
int times = 0;
while(read_case())
{
printf("Case %d: ", ++times);
solve();
}
return 0;
}
【UVA】1342 - That Nice Euler Circuit(几何+欧拉定理)
标签:style blog http color os io ar for 2014
原文地址:http://blog.csdn.net/u013451221/article/details/38933199