zoukankan      html  css  js  c++  java
  • 2017-3-2校内训练

    丧病出题人。我提答搜索顺序写反了,交完才发现,改完完爆std……219/300

    T1.Anivia 的几何题

    题目大意:给定w个正方形的两个对角坐标,求横坐标0~n-1,纵坐标0~m-1内各整点是否被矩形覆盖。(1<=n,m<=100,w<=10,坐标均为整数且在[-100,200]内)

    思路:出题人为了“让初中学弟也能做出来”出的题。根据两个对角点可以算出正方形其他顶点的坐标,每个整点枚举矩形算下叉积就可以了。可以把所有坐标乘以2,这样所有运算都是整数,可以避免实数类型一些不必要的麻烦。

    #include<cstdio>
    #define MN 10
    struct P{int x,y;P(int x=0,int y=0):x(x),y(y){}}p[4][MN+5];
    P operator-(P a,P b){return P(a.x-b.x,a.y-b.y);}
    int operator*(P a,P b){return a.x*b.y-a.y*b.x;}
    int cal(P a,P b,P c){return (b-a)*(c-a);}
    int main()
    {
        int n,m,w,i,j,k,px,py;
        scanf("%d%d%d",&n,&m,&w);
        for(i=0;i<w;++i)
        {
            scanf("%d%d%d%d",&p[0][i].x,&p[0][i].y,&p[2][i].x,&p[2][i].y);
            p[0][i].x*=2;p[0][i].y*=2;p[2][i].x*=2;p[2][i].y*=2;
            px=(p[0][i].x+p[2][i].x)/2;py=(p[0][i].y+p[2][i].y)/2;
            p[1][i].x=px+py-p[0][i].y;p[1][i].y=py-px+p[0][i].x;
            p[3][i].x=px-py+p[0][i].y;p[3][i].y=py+px-p[0][i].x;
        }
        for(i=0;i<n;++i,puts(""))for(j=0;j<m;++j,putchar(k<w?'#':'.'))for(k=0;k<w;++k)
        {
            P x(i<<1,j<<1);int a,b,c,d;
            a=cal(p[0][k],p[1][k],x);b=cal(p[1][k],p[2][k],x);
            c=cal(p[2][k],p[3][k],x);d=cal(p[3][k],p[0][k],x);
            if((!a||!c||(a<0^c>0))&&(!b||!d||(b<0^d>0)))break;    
        }
    }

    T2.Anivia 的质数

    题目大意:求[l,r]内有多少个各位数字都是质数的质数。(1<=l<=r<=10^15,r-l<=10^9)

    思路:一位数的质数只有2,3,5,7,[l,r]内的各位都是质数的数字数量实际上只有约4^9个,搜索出来,用预处理出的素数表暴力判断素数就有40分了(我的做法)。出题人给的正解是拿预处理出的素数暴力去[l,r]里筛,可以分段筛避免爆空间。我不知道1s是怎么筛10亿的,复杂度O(能过)。

    40/100(假装A了)

    #include<cstdio>
    #define ll long long
    #define MX 33333360
    #define MP 2051000
    const int o[5]={0,2,3,5,7};
    int l[20],r[20],p[20],ans,pr[MP+5],pn,f[MX/30+5];
    bool check(ll x)
    {
        for(int i=1;(ll)pr[i]*pr[i]<=x;++i)
            if(x%pr[i]==0)return false;
        return true;
    }
    void dfs(int x,int a,int b,int c)
    {
        if(x<0)
        {
            ll x=0;
            for(int i=15;i--;)x=x*10+p[i];
            if(check(x))++ans;
            return;
        }
        for(int i=0;i<5;++i)
            if((!a||i)&&(b||o[i]>=l[x])&&(c||o[i]<=r[x]))
                p[x]=o[i],dfs(x-1,a||o[i],b||o[i]>l[x],c||o[i]<r[x]);
    }
    int get(int p){return f[p/30]&(1<<p);}
    void fill(int p){f[p/30]|=(1<<p);}
    int main()
    {
        ll x;int i,j;
        for(i=2;i<=MX;++i)
        {
            if(!get(i))pr[++pn]=i;
            for(j=1;i*pr[j]<=MX;++j){fill(i*pr[j]);if(i%pr[j]==0)break;}
        }
        scanf("%I64d",&x);for(i=0;x;x/=10)l[i++]=x%10;
        scanf("%I64d",&x);for(i=0;x;x/=10)r[i++]=x%10;
        dfs(15,0,0,0);
        printf("%d
    ",ans);
    }

    T3.Anivia 的最大独立集

    题目大意:提交答案题,给一张图,求最大独立子集。

    思路:第1~4个点是小数据点,随便暴力都能过。5号点是完全图,随便输出一个点。6~7是二分图,可以网络流一下。8~10是n=1000的随机点,随便dfs+最优性剪枝就能搜到比较优的解。我后三个点的搜索顺序写反了,结果程序效率感人,得分79/100。

  • 相关阅读:
    linux(不会考特别难,牢记下面即可)
    ajax
    Javascript 和 Jquery
    开发环境及配置
    网络协议考点
    面向对象考点
    会话控制
    文件操作
    正则表达式
    自定义函数和内部函数
  • 原文地址:https://www.cnblogs.com/ditoly/p/20170302C.html
Copyright © 2011-2022 走看看