题目:

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

-6.000 1.000 

-2.000 2.000 

-5.000 6.000 

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

-5.000 -1.000 

-3.000 -1.000 

-3.000 6.000 

-5.000 6.000 

3.222 2.000 

5.000 1.000 

5.000 4.000 

3.222 3.000

【输出样例2

0.000000 2.500000

【数据范围】

50%的数据  3≤ N≤ 20, −1000 < X < 1000, −1000 < Y < 1000

100%的数据 ≤ N≤ 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;
}

 

posted on 2017-10-07 16:46  宣毅鸣  阅读(229)  评论(0编辑  收藏  举报