ASC 03 题解

来源:互联网 发布:网络金融p2p 编辑:程序博客网 时间:2024/06/08 11:58

A Areas

给不超过80个圆,问把平面分成几份?

欧拉公式,注意不同连通块

#include<bits/stdc++.h>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define ForkD(i,k,n) for(int i=n;i>=k;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=Pre[x];p;p=Next[p])#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  #define Lson (o<<1)#define Rson ((o<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,127,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define INF (2139062143)#define F (100000007)#define pb push_back#define mp make_pair #define fi first#define se second#define vi vector<int> #define pi pair<int,int>#define SI(a) ((a).size())#define ALL(a) (a).begin(), (a).end()typedef long long ll;typedef long double ld;typedef unsigned long long ull;ll mul(ll a,ll b){return (a*b)%F;}ll add(ll a,ll b){return (a+b)%F;}ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}void upd(ll &a,ll b){a=(a%F+b%F)%F;}int read(){    int x=0,f=1; char ch=getchar();    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}    return x*f;} ll sqr(ll a){return a*a;}ld sqr(ld a){return a*a;}double sqr(double a){return a*a;}const double eps=1e-8;int dcmp(double x) {    if (fabs(x)<eps) return 0; else return x<0 ? -1 : 1; }ld PI = 3.141592653589793238462643383;class P{public:    double x,y;    P(double x=0,double y=0):x(x),y(y){}    friend long double dis2(P A,P B){return sqr(A.x-B.x)+sqr(A.y-B.y);  }    friend long double Dot(P A,P B) {return A.x*B.x+A.y*B.y; }    friend long double Length(P A) {return sqrt(Dot(A,A)); }    friend long double Angle(P A,P B) {return acos(Dot(A,B) / Length(A) / Length(B) ); }    friend P operator- (P A,P B) { return P(A.x-B.x,A.y-B.y); }    friend P operator+ (P A,P B) { return P(A.x+B.x,A.y+B.y); }    friend P operator* (P A,double p) { return P(A.x*p,A.y*p); }    friend P operator/ (P A,double p) { return P(A.x/p,A.y/p); }    friend bool operator< (const P& a,const P& b) {return dcmp(a.x-b.x)<0 ||(dcmp(a.x-b.x)==0&& dcmp(a.y-b.y)<0 );}}; bool operator==(const P& a,const P& b) {    return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y) == 0;} typedef P V;double Cross(V A,V B) {return A.x*B.y - A.y*B.x;}double Area2(P A,P B,P C) {return Cross(B-A,C-A);}P GetLineIntersection(P p,V v,P Q,V w){    V u = p-Q;    double t = Cross(w,u)/Cross(v,w);    return p+v*t;}P GetLineIntersectionB(P p,V v,P Q,V w){    return GetLineIntersection(p,v-p,Q,w-Q);}bool SegmentProperIntersection(P a1,P a2,P b1,P 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 OnSegment(P p,P a1,P a2) {    return dcmp(Cross(a1-p,a2-p)) == 0 && dcmp(Dot(a1-p,a2-p))<=0;}P read_point() {    P a;    scanf("%lf%lf",&a.x,&a.y);    return a;   } typedef vector<P> Polygon;double PolygonArea(Polygon &p) {    double area=0;    int n=p.size();    For(i,n-2) area+=Cross(p[i]-p[0],p[i+1]-p[0]);    return area/2;} struct Edge{    int from,to;    double ang;    Edge(int _from,int _to,double _ang):from(_from),        to(_to),ang(_ang){}};#define MAXN (11111+10)struct PSLG {    int n,m,face_cnt;    ld x[MAXN],y[MAXN];    vector<Edge> edges;    vi G[MAXN];    int vis[MAXN*2],left[MAXN*2],prev[MAXN*2];    vector<Polygon> faces;    double area[MAXN];    void init(int n) {        this->n=n;        Rep(i,n) G[i].clear();        edges.clear();        faces.clear();    }    double getAngle(int from,int to) {        return atan2(y[to]-y[from],x[to]-x[from]);    }    void AddEdge(int from,int to) {        edges.pb(Edge(from,to,getAngle(from,to)));        edges.pb(Edge(to,from,getAngle(to,from)));        m=SI(edges);        G[from].pb(m-2);        G[to].pb(m-1);    }    void Build() {         Rep(u,n) {            int d=SI(G[u]);            Rep(i,d) {                Fork(j,i+1,d-1) {                    if (edges[G[u][i]].ang>edges[G[u][j]].ang) {                        swap(G[u][i],G[u][j]);                    }                }            }            Rep(i,d) {                prev[G[u][(i+1)%d]]=G[u][i];            }        }        MEM(vis)        face_cnt=0;        Rep(u,n) {            Rep(i,SI(G[u])) {                int e=G[u][i];                if (!vis[e]) {                    face_cnt++;                    Polygon poly;                    while(1) {                        vis[e]=1;                        left[e]=face_cnt;                        int from = edges[e].from;                        P p(x[from],y[from]);                        poly.pb(p);                        e=prev[e^1];                        if (e==G[u][i]) break;                    }                    faces.pb(poly);                }            }         }        Rep(i,face_cnt) {            area[i]=PolygonArea(faces[i]);        }    }}g;int n, sz, m;int L,W;P p1[MAXN],p2[MAXN];void find_path() {    vector<P> v;    Rep(i,n) {        Fork(j,i+1,n-1)            if (dcmp(Cross(p2[i]-p1[i],p2[j]-p1[j])!=0)) {                P p=GetLineIntersectionB(p1[i],p2[i],p1[j],p2[j]);                v.pb(p);            }    }    sort(ALL(v));    v.erase( unique(ALL(v)), v.end() );    sz=SI(v);//    Rep(i,sz) cout<<v[i].x<<' '<<v[i].y<<endl;    g.init(sz);    Rep(i,sz) g.x[i]=v[i].x,g.y[i]=v[i].y;    Rep(i,n) {        vector<P> ve;        Rep(j,n) if (i!=j) {            if (dcmp(Cross(p2[i]-p1[i],p2[j]-p1[j])!=0)) {                P p=GetLineIntersectionB(p1[i],p2[i],p1[j],p2[j]);                ve.pb(p);            }        }        sort(ALL(ve));        ve.erase( unique(ALL(ve)), ve.end() );        vector<int> vid;        Rep(j,SI(ve)) {            Rep(k,sz) {                if (v[k]==ve[j]) {                    vid.pb(k);break;                }            }        }//      Rep(j,SI(ve)) cout<<vid[j]<<' ';puts("");        for(int j=1;j<SI(ve);j++) if (vid[j]!=vid[j-1]){            g.AddEdge(vid[j],vid[j-1]);        }    }    g.Build();}int isPointInPolygon(P p,Polygon poly) {    int wn=0;    int n=poly.size();    Rep(i,n) {        if (OnSegment(p,poly[i],poly[(i+1)%n])) return -1;        int k=dcmp(Cross(poly[(i+1)%n]-poly[i],p-poly[i]));        int d1 = dcmp(poly[i].y-p.y);        int d2 = dcmp(poly[(i+1)%n].y-p.y);        if ( k > 0 && d1 <= 0 && d2 > 0 ) wn++;        if ( k < 0 && d2 <= 0 && d1 > 0 ) wn--;    }    if (wn!=0) return 1;    return 0;}P GetLineProjection(P p,P A,P B) {    V v=B-A;    return A+v*(Dot(v,p-A)/Dot(v,v));}bool is_intesect(Polygon poly,P o,double r) {    int n=SI(poly);    if (isPointInPolygon(o,poly)==1) return 1;    Rep(i,n) {        if (dcmp(Length(poly[i]-o)-r)<0) return 1;    }    Rep(i,n) {        P A=poly[i],B=poly[(i+1)%n];        if (dcmp(Length((A+B)/2-o)-r)<0) return 1;    }    Rep(i,n) {        P A=poly[i],B=poly[(i+1)%n];        P C=GetLineProjection(o,A,B);        if (C==A||C==B) continue;        if (dcmp(Length(C-o)-r)<0 && OnSegment(C,A,B)) return 1;    }    return 0;}int main(){    freopen("areas.in","r",stdin);    freopen("areas.out","w",stdout);    n=read();    Rep(i,n) {        p1[i]=read_point(); p2[i]=read_point();    }    find_path();    vector<double > ans;    Rep(i,g.face_cnt) if (dcmp(g.area[i])>0) {        ans.pb(g.area[i]);    }    sort(ALL(ans));    cout<<SI(ans)<<endl;    Rep(i,SI(ans)) printf("%.4lf\n",ans[i]);    return 0;}

B Beloved Sons

国王要给王子们安排婚事,每个王子都有一个权重Ai,目标是使所有与心爱女孩结婚的王子们的权重的2范数最大。

二分图最大权匹配,km裸题

#include<bits/stdc++.h> using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define ForkD(i,k,n) for(int i=n;i>=k;i--)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=pre[x];p;p=next[p])#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  #define Lson (o<<1)#define Rson ((o<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,0x3f,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define MEMx(a,b) memset(a,b,sizeof(a));#define INF (0x3f3f3f3f)#define F (1000000007)#define pb push_back#define mp make_pair#define fi first#define se second#define vi vector<int> #define pi pair<int,int>#define SI(a) ((a).size())#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;#define PRi2D(a,n,m) For(i,n) { \                        For(j,m-1) cout<<a[i][j]<<' ';\                        cout<<a[i][m]<<endl; \                        } #pragma comment(linker, "/STACK:102400000,102400000")#define ALL(x) (x).begin(),(x).end()#define gmax(a,b) a=max(a,b);#define gmin(a,b) a=min(a,b);typedef long long ll;typedef long double ld;typedef unsigned long long ull;ll mul(ll a,ll b){return (a*b)%F;}ll add(ll a,ll b){return (a+b)%F;}ll sub(ll a,ll b){return ((a-b)%F+F)%F;}void upd(ll &a,ll b){a=(a%F+b%F)%F;}inline int read(){    int x=0,f=1; char ch=getchar();    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}    return x*f;} ll costA[410]; namespace KM{    const int N=405;    bool b[410][410];    const ll inf=1e15;    ll n,nl,nr,m,z,py,x,y,i,j,p,lk[N],pre[N];    bool vy[N];    ll lx[N],ly[N],d,w[N][N],slk[N];ll ans;    ll work(int nl,int nr){ // nl nr w      n=max(nl,nr);//      For(i,nl) For(j,nr) w[i][j]=max(0,f[i][j]);    For(i,nl) For(j,nr) w[i][j]=0;    MEM(b)    For(x,nl) {        int m=read(),y;        while(m--)            scanf("%d",&y),w[y][x]=max(w[y][x],costA[x]),b[x][y]=1;    }//    For(i,nl) {//      For(j,nr) cout<<w[i][j]<<' ';cout<<endl;//  }      for(i=1;i<=n;i++)for(j=1;j<=n;j++)lx[i]=max(lx[i],w[i][j]);      for(i=1;i<=n;i++){        for(j=1;j<=n;j++)slk[j]=inf,vy[j]=0;        for(lk[py=0]=i;lk[py];py=p){          vy[py]=1;d=inf;x=lk[py];          for(y=1;y<=n;y++)if(!vy[y]){            if(lx[x]+ly[y]-w[x][y]<slk[y])slk[y]=lx[x]+ly[y]-w[x][y],pre[y]=py;            if(slk[y]<d)d=slk[y],p=y;          }          for(y=0;y<=n;y++)if(vy[y])lx[lk[y]]-=d,ly[y]+=d;else slk[y]-=d;        }        for(;py;py=pre[py])lk[py]=lk[pre[py]];      }      for(i=1;i<=n;i++)ans+=lx[i]+ly[i];//    printf("%lld\n",ans);    for(i=1;i<=nl;i++){        printf("%I64d ",w[lk[i]][i]?((b[i][lk[i]])?lk[i]:0):0);    }    }}int n,m;int main(){//  freopen("b.in","r",stdin);    freopen("beloved.in","r",stdin);    freopen("beloved.out","w",stdout);    int n=read();    For(i,n) costA[i]=read();    For(i,n) costA[i]=costA[i]*costA[i];    KM::work(n,n);    return 0;}

D Data Transmission

求一个分层图的阻塞流(blocking flow)。(n = 1.5k; m = 0.3M)

HLLP网络流,裸交能过。

E Strong Defence

一个有向图,要给一些边染色,使得所用的颜色最多,且S到T的任意路径的都包含所有颜色。

答案下界是点S到点T的最短路长度。
构造,我们把点按到S的距离分层,每一次保证把第i层和第i+1层割开,显然成立.

F Weird Dissimilarity

字符c1和c2的距离为d(c1, c2),已知两个字符串s和t,现在要找长度相等的两个字符串a和b,使得s是a的子序列,t是b的子序列,且a和b的距离最小。

dp[i][j]表示a的前i个字母和b的前j个字母匹配的最优代价。
然后dp做法显然。
注意读入的字符为>32的可见字符,如果用char读入,char的范围是-128~+127,hash时要注意。

G PL/Cool

为PL/Cool写一个解释器,它有两种操作:define op1 op2把以后所有的op1都用op2替换,替换是可以一直迭代的,但重复define和产生环的define应该被无视;print expr,其中expr是个四则运算表达式,输出先根据define替换再表达求值的结果。

不敢开……

I Two Cylinders

求轴垂直相交的两个高度无限圆柱的相交区域体积。

直接辛普森积分

#include<bits/stdc++.h>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define ForkD(i,k,n) for(int i=n;i>=k;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=Pre[x];p;p=Next[p])#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])  #define Lson (o<<1)#define Rson ((o<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define MEMI(a) memset(a,127,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define INF (2139062143)#define pb push_back#define mp make_pair #define fi first#define se second#define vi vector<int> #define pi pair<int,int>#define SI(a) ((a).size())#define Pr(kcase,ans) printf("Case %d: %lld\n",kcase,ans);#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[i]<<endl;#define PRi2D(a,n,m) For(i,n) { \                        For(j,m-1) cout<<a[i][j]<<' ';\                        cout<<a[i][m]<<endl; \                        } typedef long long ll;typedef unsigned long long ull;typedef long double ld;int read(){    int x=0,f=1; char ch=getchar();    while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}    while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}    return x*f;} double r1,r2;ld PI = 3.141592653589793238462643383;namespace Simpson{    double a;    double f(double k) {        double lamda=sqrt(r2*r2-k*k);        if (lamda>=r1) return PI*r1*r1;        if (fabs(lamda)<1e-8) return 0;        double xita=acos(lamda/r1);        double S1=sqrt(r1*r1-lamda*lamda)*lamda*2;        double S2=(PI-2*xita)*r1*r1;//      cout<<S1<<' '<<S2<<' '<<S1+S2<<endl;        return S1+S2;    }    double simpson(double a,double b) {        double c=(a+b)/2;        return (f(a)+f(b)+4*f(c)) * (b-a) / 6;    }    double asr(double a,double b,double eps,double A) {        double c=(a+b)/2;        double l=simpson(a,c),r=simpson(c,b);        if (fabs(l+r-A)<=15*eps) return l+r+(l+r-A)/15.;        return asr(a,c,eps,l)+asr(c,b,eps,r);    }    double asr(double a,double b,double eps) {        return asr(a,b,eps,simpson(a,b));    }}int main(){    freopen("twocyl.in","r",stdin);    freopen("twocyl.out","w",stdout);    cin>>r1>>r2;    if (r1>r2) swap(r1,r2);    double s=PI*r1*r1*r2;    printf("%.4lf\n",Simpson::asr(0,r2,1e-8)*2);    return 0;}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 大学没交学费会怎么办 交学费收据丢了怎么办 上海浦东金科苑幼儿园统筹怎么办 红酒瓶塞掉了怎么办 红酒瓶塞丢了怎么办 收入证明没有公章怎么办 父母没工作怎么办签证 在温哥华怎么办新西兰签证 上班第一天无聊怎么办 上班紧张不自信怎么办 销售到了30岁怎么办 转行会计没经验怎么办 澳洲coe被取消怎么办 父母不同意嫁远怎么办 家人不同意我们在一起怎么办 语言课申请不到怎么办 墨尔本大学均分不够怎么办 去澳洲旅游签证怎么办 换新护照澳大利亚签证怎么办 大学错过交学费日期怎么办 留学加拿大申请工签被拒怎么办 英国大学挂科怎么办 小孩子学不进去怎么办 大学生学不进去怎么办 高考没考上本科怎么办 想读书家里没钱怎么办 考上大学没钱上怎么办 儿子没考上大学怎么办 后悔没上大学怎么办 把学费花了怎么办 临床预科挂科怎么办 补录了预科怎么办 美国预科没过怎么办 出国留学报到证怎么办 本科绩点2.93怎么办 在美国被抢劫怎么办 去美国留学费用怎么办 被美国大学停学怎么办 雅思作文字数不够怎么办 英国选修课挂科怎么办 英国双申保证金怎么办