zoukankan      html  css  js  c++  java
  • 2017.6.11 NOIP模拟赛

    题目链接:

    http://files.cnblogs.com/files/TheRoadToTheGold/2017-6.11NOIP%E6%A8%A1%E6%8B%9F%E8%B5%9B.zip

    期望得分:100+30+100=230

    实际得分:0+30+100=130

    T1 盘子序列

    数据离散化,模拟栈

    将盘子大小离散化 1——n

    指针now开始指向1,依次递增,模拟初始盘堆A最上面的盘子

    用a[i]存储收到的离散化之后的第i个盘子的大小,收到盘子的顺序也看做一个栈,记为栈C

    st[]模拟盘堆B, top指针指向栈顶

     

    然后分4种情况讨论

    1、a[i]=now 初始盘堆A的最上面的盘子直接放到了栈C  now++

    2、st[i]=now 盘堆B最上面的盘子放到栈C ,top--

    3、盘堆A还有盘子,盘堆AB的顶端都不等于now,一直把A的盘子往B上放,直到等于now 或A没有盘子了

    4、都不符合上面3种,有危险

    最后判断st即B是否是升序排列,是则没有危险,否则有危险

    #include<cstdio>
    #include<algorithm>
    #define N 100001
    using namespace std;
    int n,now,x;
    int st[N],top,a[N];
    bool ok;
    struct node
    {
        int num,id;
    }e[N];
    bool cmp(node p,node q)
    {
        return p.num<q.num;
    }
    int main()
    {
        freopen("disk.in","r",stdin);
        freopen("disk.out","w",stdout);
        while(scanf("%d",&n)!=EOF)
        {
            for(int i=1;i<=n;i++) scanf("%d",&e[i].num),e[i].id=i;
            sort(e+1,e+n+1,cmp);
            for(int i=1;i<=n;i++) a[e[i].id]=i;
            ok=0; top=0; now=1;
            for(int i=1;i<=n;i++)
            {
                if(ok) continue;
                if(a[i]==now) now++;
                else if(top&&a[i]==st[top]) top--;
                else if(now<n&&a[i]!=now) 
                {
                    while(a[i]!=now && now<n) st[++top]=now++;
                    now++;
                }
                else  { printf("J
    "); ok=true;}
            }
            if(top>1&&!ok)
            {
                for(int i=1;i<top;i++) 
                 if(st[i]>st[i+1])
                 {
                      printf("J
    ");
                     ok=true; break;
                 }
            }
            if(!ok) printf("Y
    ");
        }
    }
    View Code

     0分原因:

    第三种情况:

    else if(now<n&&a[i]!=now)
    {
      while(a[i]!=now && now<n) st[++top]=now++;
      now++;
    }

    while里漏了now<n,无限循环RE

    T2 四轮车

    离散化坐标

    枚举两个点1、2固定一条边,根据正方形四边相等

    那么

    x3=x2+y2-y1; y3=y2+x1-x2;
    x4=x1+y2-y1; y4=y1+x1-x2;

    判断这两个点是否出现过

    因为可能有重复点,所以去重后,设点出现了k次

    没找到一个满足条件的,ans+=k1*k2*k3*k4

    正方形的4条边都有可能是枚举的那条边,所以最后ans/4

    代码中判断3、4是否存在的方法:

    设离散化后的横坐标为nx,纵坐标为ny

    [nx][ny] 出现过 (有序数对(nx,ny))

    同时,hash_x[nx]=x,hash_y[ny]=y

    hash[]:排序后的原数据

    #include<cstdio>
    #include<algorithm>
    #define N 1001
    
    using namespace std;
    
    int n,x[N],y[N],ans;
    int sum[N][N];
    bool v[N];
    int eg[N][N];
    int hashx[N+1],hashy[N+1],totx,toty,nx,ny;
    int newx[N],newy[N];
    
    int x1,x2,y1,y2,x3,x4,y3,y4,k1,k2,k3,k4;
    void solve(int a,int b)
    {
        x1=x[a]; x2=x[b]; y1=y[a]; y2=y[b];
        x3=x2+y2-y1; y3=y2+x1-x2;
        x4=x1+y2-y1; y4=y1+x1-x2;
        nx=lower_bound(hashx+1,hashx+totx+1,x3)-hashx;
        ny=lower_bound(hashy+1,hashy+toty+1,y3)-hashy;
        if(!(eg[nx][ny] && hashx[nx]==x3 && hashy[ny]==y3)) return ;
        k3=sum[nx][ny];
        nx=lower_bound(hashx+1,hashx+totx+1,x4)-hashx;
        ny=lower_bound(hashy+1,hashy+toty+1,y4)-hashy;
        if(!(eg[nx][ny] && hashx[nx]==x4 && hashy[ny]==y4)) return ;
        k4=sum[nx][ny];
        k1=sum[newx[a]][newy[a]]; k2=sum[newx[b]][newy[b]];
        ans+=k1*k2*k3*k4;
        //if(k1*k2*k3*k4) printf("%d,%d %d,%d %d,%d %d,%d
    ",x1,y1,x2,y2,x3,y3,x4,y4);
    //    return k1*k2*k3*k4;
    }
    
    int main()
    {
        /*freopen("car.in","r",stdin);
        freopen("car.out","w",stdout);*/
        scanf("%d",&n);
        for(int i=1;i<=n;i++) 
        {
            scanf("%d%d",&x[i],&y[i]);
            hashx[i]=x[i]; hashy[i]=y[i];
        }
        sort(hashx+1,hashx+n+1);
        sort(hashy+1,hashy+n+1);
        totx=unique(hashx+1,hashx+n+1)-(hashx+1);
        toty=unique(hashy+1,hashy+n+1)-(hashy+1);
        for(int i=1;i<=n;i++)
        {
            nx=lower_bound(hashx+1,hashx+totx+1,x[i])-hashx;
            ny=lower_bound(hashy+1,hashy+toty+1,y[i])-hashy;
            newx[i]=nx; newy[i]=ny;
            sum[nx][ny]++;
            if(!eg[nx][ny]) eg[nx][ny]=i;
            else  v[i]=true;
        }
        for(int i=1;i<=n;i++)
        {
            if(v[i]) continue;
            for(int j=1;j<=n;j++)
            {
                if(v[j] || i==j) continue;
                solve(i,j);
                //if(k) printf("%d %d %d
    ",i,j,k);
            }
        }
        printf("%d",ans/4);
    }
    View Code

    考场上打的30分暴力:

    n^4枚举4个点,如果能构成正方形,ans++

    构成正方形的4个点,固定住1个,剩余3个有3!种排法

    所以同一个正方形会被重复计算4*3!=24次

    最后ans/24

    #include<cstdio>
    #include<queue>
    #define ref(x) for(x=1;x<=n;x++)
    #define N 1001
    
    using namespace std;
    
    int n,x[N],y[N],ans;
    
    inline int Length(int i,int j)
    {
        return (x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]) ;
    } 
    
    int main()
    {
        freopen("car.in","r",stdin);
        freopen("car.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
        int a,b,c,d;
        bool ok;
        ref(a)
         ref(b)
         {
             if(a==b) continue;
             ref(c)
             {
                 if(c==a||c==b) continue;
                 ref(d)
                 {
                     if(d==a||d==b||d==c) continue;
                     ok=false;
                    if((Length(a,b)==Length(b,c)) && (Length(b,c)==Length(c,d)) && (Length(c,d)==Length(d,a))) ok=true;
                    else if((Length(a,b)==Length(b,d)) && (Length(b,d)==Length(d,c)) && (Length(d,c)==Length(c,a))) ok=true;
                    else if((Length(a,c)==Length(c,b)) && (Length(c,b)==Length(b,d)) && (Length(b,d)==Length(d,a))) ok=true;
                    else if((Length(a,c)==Length(c,d)) && (Length(c,d)==Length(d,b)) && (Length(d,b)==Length(b,a))) ok=true;
                    else if((Length(a,d)==Length(d,b)) && (Length(d,b)==Length(b,c)) && (Length(b,c)==Length(c,a))) ok=true;
                    else if((Length(a,d)==Length(d,c)) && (Length(d,c)==Length(c,b)) && (Length(c,b)==Length(b,a))) ok=true;
                    if(ok) ans++;
                }
            }
         }
         printf("%d",ans/24);
    }
    View Code

    T3 点名

    注:本题题目有误,应该是询问身高第k矮

    法一:主席树查询区间k值

    #include<cstdio>
    #include<algorithm>
    #define N 30001
    
    using namespace std;
    
    int n,m,now,x,tot,ans;
    long long high[N],tmp[N];
    int hash[N];
    int sum[N*4];
    
    int read1(int &x)
    {
        x=0; char c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); }
    }
    long long read2(long long &x)
    {
        x=0; char c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } 
    }
    void output(long long x)
    {
        if(x/10) output(x/10);
        putchar(x%10+'0');
    }
    
    struct President
    {
        void insert(int k,int l,int r,int pos)
        {
            sum[k]++;
            if(l==r) return;
            int mid=l+r>>1;
            if(pos<=mid) insert(k<<1,l,mid,pos);
            else insert(k<<1|1,mid+1,r,pos);
        }
        int query(int k,int l,int r,int w)
        {
            if(l==r) return l;
            int mid=l+r>>1;
            if(w<=sum[k<<1]) return query(k<<1,l,mid,w);
            return query(k<<1|1,mid+1,r,w-sum[k<<1]);
        }
    };
    
    President Tree;
    
    int main()
    {
        freopen("rollcall.in","r",stdin);
        freopen("rollcall.out","w",stdout);
        read1(n); read1(m);
        int tot=n;
        for(int i=1;i<=n;i++) read2(high[i]),tmp[i]=high[i];
        sort(high+1,high+n+1);
        tot=unique(high+1,high+n+1)-(high+1);
        for(int i=1;i<=n;i++) hash[i]=lower_bound(high+1,high+tot+1,tmp[i])-high;
        
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&x);
            while(now!=x)
            {
                Tree.insert(1,1,tot,hash[now+1]);
                now++;
            }
            ans=Tree.query(1,1,tot,i);
            output(high[ans]);
            puts("");
        }
    }
    View Code

     法二:堆

    http://www.cnblogs.com/TheRoadToTheGold/p/6995106.html

  • 相关阅读:
    Java基础:基本类型
    完全干净的卸载VS2013
    git本地仓库首次push到远程仓库出现错误 ! [rejected] master -> master (fetch first)
    运行VS出现warning C4996错误的解决办法
    xbmc-android的编译
    linux执行sh,出现/bin/sh^M: bad interpreter: No such file or directory
    Ubuntu配置android-vlc编译环境(2015-11-05)
    a80修改默认4k输出,官方代码锁死了
    ubuntu12.04平台下a80编译环境搭建
    编译java代码出现 错误: 需要class, interface或enum 提示
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6985388.html
Copyright © 2011-2022 走看看