用这个公式,只要求出n和m,r就是答案了
n个点直接求,注意染色判重
m条边怎么办?首先有n条边,是画出来的,但有可能线段相交使得边数增大。
这时候,枚举所有点,对于每个点,枚举所有线段,如果该点严格在该线段内,那么边数+=1。
我暂时不知道为什么,就是这样。
//Hello. I'm Peter.
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double ld;
#define peter cout<<"i am peter"<<endl
#define input freopen("data.txt","r",stdin)
#define randin srand((unsigned int)time(NULL))
#define INT (0x3f3f3f3f)*2
#define LL (0x3f3f3f3f3f3f3f3f)*2
#define gsize(a) (int)a.size()
#define len(a) (int)strlen(a)
#define slen(s) (int)s.length()
#define pb(a) push_back(a)
#define clr(a) memset(a,0,sizeof(a))
#define clr_minus1(a) memset(a,-1,sizeof(a))
#define clr_INT(a) memset(a,INT,sizeof(a))
#define clr_true(a) memset(a,true,sizeof(a))
#define clr_false(a) memset(a,false,sizeof(a))
#define clr_queue(q) while(!q.empty()) q.pop()
#define clr_stack(s) while(!s.empty()) s.pop()
#define rep(i, a, b) for (int i = a; i < b; i++)
#define dep(i, a, b) for (int i = a; i > b; i--)
#define repin(i, a, b) for (int i = a; i <= b; i++)
#define depin(i, a, b) for (int i = a; i >= b; i--)
#define pi 3.1415926535898
#define eps 1e-6
#define MOD 1000000007
#define MAXN
#define N 500
#define M
int dcmp(double x){
if(fabs(x)<eps) return 0;
else if(x<0) return -1;
else return 1;
}
int n,nume,numv,numr;
struct Point
{
double x,y;
Point(){};
Point(double xx,double yy):x(xx),y(yy){};
friend bool operator<(const Point a,const Point b){
if(dcmp(a.x-b.x)!=0) return a.x<b.x;
else return a.y<b.y;
}
}poi[N],vec[N];
typedef Point Vector;
map<Point,bool>vis;
vector<Point>newpoi;
void read(Point &b){
scanf("%lf %lf",&b.x,&b.y);
}
Vector operator +(const Vector a,const Vector b){
return Vector(a.x+b.x,a.y+b.y);
}
Vector operator -(const Vector a,const Vector b){
return Vector(a.x-b.x,a.y-b.y);
}
Vector operator *(const double a,const Vector b){
return Vector(a*b.x,a*b.y);
}
Vector operator *(const Vector b,const double a){
return Vector(a*b.x,a*b.y);
}
double operator *(const Vector a,const Vector b){
return a.x*b.x+a.y*b.y;
}
double operator &(const Vector a,const Vector b){
return a.x*b.y-a.y*b.x;
}
Point LineIntersect(Point p,Vector v,Point q,Vector w){
Vector u=p-q;
double t=(w&u)/(v&w);
return p+v*t;
}
bool SegmentStrictlyIntersect(Point p1,Vector v,Point q1,Vector w){
Point p2=p1+v;
Point q2=q1+w;
Point p1p2=p2-p1,p1q1=q1-p1,p1q2=q2-p1;
double c1=p1p2&p1q1,c2=p1p2&p1q2;
Point q1q2=q2-q1,q1p1=p1-q1,q1p2=p2-q1;
double c3=q1q2&q1p1,c4=q1q2&q1p2;
return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}
bool PointStrictlyOnSegment(Point p,Point q1,Vector w){
Point q2=q1+w;
Point pq1=q1-p,pq2=q2-p;
double c1=pq1&pq2,c2=pq1*pq2;
return dcmp(c1)==0 && dcmp(c2)<0;
}
int main()
{
int kase=1;
while(~scanf("%d",&n) && n)
{
vis.clear();
newpoi.clear();
repin(i,1,n)
{
read(poi[i]);
if(!vis[poi[i]])
{
vis[poi[i]]=true;
newpoi.pb(poi[i]);
}
}
n-=1;
repin(i,1,n)
{
vec[i]=poi[i+1]-poi[i];
}
repin(i,1,n)
{
repin(j,i+1,n)
{
if(SegmentStrictlyIntersect(poi[i],vec[i],poi[j],vec[j]))
{
Point p=LineIntersect(poi[i],vec[i],poi[j],vec[j]);
if(!vis[p])
{
vis[p]=true;
newpoi.pb(p);
}
}
}
}
int len_newpoi=gsize(newpoi);
numv=len_newpoi;
nume=n;
//求边数
rep(i,0,len_newpoi)
{
Point p=newpoi[i];
repin(j,1,n)
{
if(PointStrictlyOnSegment(p,poi[j],vec[j]))
{
nume+=1;
}
}
}
//Euler told us: numv-nume+numr==2;
//So numr=nume-numv+2;
numr=nume-numv+2;
printf("Case %d: There are %d pieces.\n",kase++,numr);
}
}