1. 程式人生 > >第n次考試

第n次考試

center family 3.0 代碼 fine last 數據 can color

題目:

1.堆方塊

【題目描述】

給定N個方塊,排成一行,將它們編號1到N。

再給出P個操作:

M i j表示將i所在的那一堆移到j所在那一堆的頂上。

C i表示一個詢問,詢問i下面有多少個方塊。

你需要寫一個程序來完成這些操作。

【輸入文件】

第一行一個整數P。

接下來P行,每行一個操作。

【輸出文件】

若幹行,對應每個詢問的答案。

【樣例輸入】

6

M 1 6

C 1

M 2 4

M 2 6

C 3

C 4

【樣例輸出】

1

0

2

【數據規模】

對於100%的數據 1<=P<=100000,1<=i,j<=N,1<=N<=30000

2.點的數目

【題目描述】

在一維數軸上有N個正整數點,以1..N進行編號。某些點比較特殊,稱之為“怪點”。給定M段區間,每段區間有且僅有一個“怪點”。請根據這M個區間,推斷出總共有多少個“怪點”。如果推斷不出來,則輸出-1

【輸入格式】

第一行為NM。緊接著的M行,每行代表一個區間。

【輸出格式】

怪點的數目。推斷不出,則輸出-1

【輸入樣例】

5 3
1 4
2 5
3 4

【輸出樣例】

1

【樣例解釋】

由第3段區間知道,點3或點4為怪點,而第12段區間恰好包括了點3或點4

【數據範圍】

30%的數據,1<=N<=1000,1<=M<=200

100%數據,1 <= N <= 200,000,1 <= M <= 100,000

3. DORUCAK

【題目描述】

平面上y軸左邊和右邊各有一個凸多邊形。求一條直線y=Ax+B,使得將這兩個多邊形都分成面積相等的兩部分。

【輸入格式】

第一行一個整數n,表示一個凸多邊形有n個頂點;接下來的n行,每行兩個實數x,y,表示這n個頂點的坐標;這個凸多邊形在y軸左邊。

n+2行是一個整數m,表示國一個凸多邊形有m個頂點,接下來的m行,每行兩個實數x,y,表示這m個頂點的坐標。這個凸多邊形在y軸右邊。

兩個凸多邊形的頂點都是按逆時針的順序給出,多邊形中沒有三點共線。

【輸出格式】

輸出AB。答案保證存在,且唯一。A,B允許的誤差範圍為±0.001。

【輸入樣例1

3

-6.000 1.000

-2.000 2.000

-5.000 6.000

5

1.000 -1.000

3.000 -2.000

6.000 0.000

4.000 3.000

1.000 2.000

【輸出樣例1

-0.319961 1.556489

【輸入樣例2

4

-5.000 -1.000

-3.000 -1.000

-3.000 6.000

-5.000 6.000

4

3.222 2.000

5.000 1.000

5.000 4.000

3.222 3.000

【輸出樣例2

0.000000 2.500000

【數據範圍】

50%的數據 3NM 20, ?1000 < X < 1000, ?1000 < Y < 1000

100%的數據 3 NM 5000 , ?1000 < X < 1000, ?1000 < Y < 1000

題解:

1.並查集,每一次合並,記錄是第幾個

2.dp+單調隊列優化

註意條件告訴我們的是:

1.i-j至少有一個奶牛

2.i-j最多有一個奶牛

然後就可以確定最大和最小的範圍

3.

計算幾何+二分

二分枚舉a,然後繼續二分枚舉b

代碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
const int N=30005;
int m,f[N],d[N],last[N],x,y,sum[N];
char s[5]; 
int find(int x)
{
    int x1;
    if (x!=f[x])x1=find(f[x]);else x1=x; 
    if (f[f[x]]!=x)d[x]+=d[f[x]];
    f[x]=x1;
    return x1;
}
int main()
{
    freopen("cubes.in","r",stdin);
    freopen("cubes.out","w",stdout); 
    scanf("%d",&m);
    for (int i=1;i<N;i++)
     {
         last[i]=1;
         f[i]=i;
     }
    while (m--)
     {
         scanf("%s%d",&s,&x);
         int x1=find(x);
         if (s[0]==M)
          {
              scanf("%d",&y);
             int y1=find(y); 
            if (x1==y1)continue;     
              f[x1]=y1;
              d[x1]=last[y1];
            last[y1]+=last[x1];
          }
         else printf("%d\n",d[x]);
     } 
    return 0; 
}
#include<bits/stdc++.h>
using namespace std;
const int INF=2147483647,N=200010;
int L[N],R[N],tr[N<<2],n,m;
int Query(int node,int l,int r,int a,int b)
{
    if(a<=0)a=1;
    if(a>b||b<=0)return 0; 
    if(l>=a&&r<=b)return tr[node];
    int mid=(l+r)>>1,ret=-INF;
    if(mid>=a)ret=Query(node<<1,l,mid,a,b);
    if(mid<b)ret=max(ret,Query(node<<1|1,mid+1,r,a,b));
    return ret;
}
void Modify(int node,int l,int r,int g,int d)
{
    if(l==r){tr[node]=d;return;}
    int mid=(l+r)>>1;
    if(mid>=g)Modify(node<<1,l,mid,g,d);
    else Modify(node<<1|1,mid+1,r,g,d);
    tr[node]=max(tr[node<<1],tr[node<<1|1]);
} 
int main()
{
    freopen("photo.in","r",stdin);
    freopen("photo.out","w",stdout);
    scanf("%d%d",&m,&n);m++;
    for(int i=1;i<=m;i++)R[i]=i-1;
    for(int i=1,a,b;i<=n;i++)
     {
        scanf("%d%d",&a,&b);
        L[b+1]=max(L[b+1],a);
        R[b]=min(R[b],a-1);
       }
    for(int i=2;i<=m;i++)L[i]=max(L[i],L[i-1]);
    for(int i=m-1;i>=1;i--)R[i]=min(R[i],R[i+1]);
    for(int i=1;i<m;i++)
     Modify(1,1,m,i,L[i]<=R[i]?Query(1,1,m,L[i],R[i])+1:-INF);
    printf("%d\n",max(-1,Query(1,1,m,L[m],R[m])));
    return 0;        
}
#include<bits/stdc++.h>
using namespace std;
const int INF=2147483647,N=200010;
int L[N],R[N],tr[N<<2],n,m;
int Query(int node,int l,int r,int a,int b)
{
    if(a<=0)a=1;
    if(a>b||b<=0)return 0; 
    if(l>=a&&r<=b)return tr[node];
    int mid=(l+r)>>1,ret=-INF;
    if(mid>=a)ret=Query(node<<1,l,mid,a,b);
    if(mid<b)ret=max(ret,Query(node<<1|1,mid+1,r,a,b));
    return ret;
}
void Modify(int node,int l,int r,int g,int d)
{
    if(l==r){tr[node]=d;return;}
    int mid=(l+r)>>1;
    if(mid>=g)Modify(node<<1,l,mid,g,d);
    else Modify(node<<1|1,mid+1,r,g,d);
    tr[node]=max(tr[node<<1],tr[node<<1|1]);
} 
int main()
{
    freopen("photo.in","r",stdin);
    freopen("photo.out","w",stdout);
    scanf("%d%d",&m,&n);m++;
    for(int i=1;i<=m;i++)R[i]=i-1;
    for(int i=1,a,b;i<=n;i++)
     {
        scanf("%d%d",&a,&b);
        L[b+1]=max(L[b+1],a);
        R[b]=min(R[b],a-1);
       }
    for(int i=2;i<=m;i++)L[i]=max(L[i],L[i-1]);
    for(int i=m-1;i>=1;i--)R[i]=min(R[i],R[i+1]);
    for(int i=1;i<m;i++)
     Modify(1,1,m,i,L[i]<=R[i]?Query(1,1,m,L[i],R[i])+1:-INF);
    printf("%d\n",max(-1,Query(1,1,m,L[m],R[m])));
    return 0;        
}
#include<bits/stdc++.h>
using namespace std;
#define sqr(x) ((x)*(x))
const int N=10005;
int n[3];
double K,B,Px,Py,Qx,Qy,X,Y,x[3][N],y[3][N],s[2];
double Xot(double x1,double y1,double x2,double y2)
{
    return x1*y2-x2*y1;
}
bool Is(double x1,double y1,double x2,double y2)
{
    double s1=Xot(x1-Qx,y1-Qy,Px-Qx,Py-Qy);
    double s2=Xot(Px-Qx,Py-Qy,x2-Qx,y2-Qy);
    if (s1*s2<=0) return false;
    X=(x1*s2+x2*s1)/(s1+s2);
    Y=(y1*s2+y2*s1)/(s1+s2);
    return true;
}
double Area(int k)
{
    Px=-1E5;Py=K*Px+B;
    Qx=1E5;Qy=K*Qx+B;
    n[2]=0;
    for (int i=1;i<=n[k];i++)
     {
        if (Is(x[k][i-1],y[k][i-1],x[k][i],y[k][i]))
         x[2][++n[2]]=X,y[2][n[2]]=Y;
        if (Xot(x[k][i]-Px,y[k][i]-Py,Qx-Px,Qy-Py)>0)
         x[2][++n[2]]=x[k][i],y[2][n[2]]=y[k][i];
     }
    double res=0;
    for (int i=2;i<n[2];i++)
     res+=Xot(x[2][i]-x[2][1],y[2][i]-y[2][1],
    x[2][i+1]-x[2][1],y[2][i+1]-y[2][1]);
    return abs(res);
}
int main()
{
    freopen("dorucak.in","r",stdin);
    freopen("dorucak.out","w",stdout);
    for (int k=0;k<2;k++)
     {
        scanf("%d",&n[k]);
        for (int i=1;i<=n[k];i++)
         scanf("%lf%lf",&x[k][i],&y[k][i]);
        x[k][0]=x[k][n[k]];
        y[k][0]=y[k][n[k]];
        for (int i=2;i<n[k];i++)
         s[k]+=Xot(x[k][i]-x[k][1],y[k][i]-y[k][1]
         ,x[k][i+1]-x[k][1],y[k][i+1]-y[k][1]);
        s[k]=abs(s[k]);
    }
    double LK=-1E5,RK=1E5;
    while (LK+1E-5<RK)
     {
        K=(LK+RK)/2.0;
        double LB=-1E5,RB=1E5;
        while (LB+1E-5<RB)
         {
            B=(LB+RB)/2.0;
            if (Area(0)*2.0<=s[0])LB=B;
            else RB=B;
         }
        B=(LB+RB)/2.0;
        if (Area(1)*2.0<=s[1])LK=K;
        else RK=K;
    }
    printf("%.6lf %.6lf\n",K,B);
    return 0;
}

第n次考試