zoukankan      html  css  js  c++  java
  • 2017.10.1北京清北综合强化班DAY1


    a
    【问题描述】
    你是能看到第一题的 friends 呢。
    ——hja
    何大爷对字符串十分有研究,于是天天出字符串题虐杀 zhx。

    何大爷今天为符串定义了新的权值计算方法。一个字符串

    由小写字母组成,字符串的权值被定义为其中出现次数最多

    的字符的次数减去出现次数最少的字符的次数。 (注意,在

    讨论出现最少的字符的时候,该字符必须至少出现一次)现在

    何大爷给你一个字符串,何大爷想知道这个字符串的所有子串

    中权值最大的权值是多少?

    【输入格式】
    第一行一个整数?,代表字符串的长度。
    接下来一行?个小写字母,代表该字符串。
    【输出格式】
    一行一个整数代表答案。
    【样例输入】
    10
    aabbaaabab
    【样例输出】
    3
    【数据范围与规定】
    3。
    60%的数据,1 ≤ ? ≤ 1000。
    对于100%的数据,1 ≤ ? ≤ 10 6 .

    题目大意:

    求一个字符串子串的最多出现次数-最少出现次数的最大值。

    题解:

    30分做法O(n^3)枚举区间 扫最大最小值

    60分做法O(26n^2)枚举区间 前缀和求最大最小值

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int n,maxx,minn,ans,sum[1020][26];
    char s[1020];
    int main(){
        scanf("%d",&n);scanf("%s",s+1);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=26;j++)sum[i][j]=sum[i-1][j];
            int z=s[i]-'a'+1;
            sum[i][z]=sum[i-1][z]+1;
        }
        for(int i=1;i<=n;i++){
            for(int j=i;j<=n;j++){
                if(i==j){
                    ans=max(ans,0);
                    continue;
                }
                maxx=-1;minn=100000;
                for(int k=1;k<=26;k++){
                    int z=sum[j][k]-sum[i-1][k];
                    if(z)minn=min(minn,z);
                    maxx=max(maxx,z);
                }
                ans=max(ans,maxx-minn);
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    60分

    枚举右端点,前缀和优化。对于当前点x,答案为

    sum[x][r]-sum[x][l-1]-(sum[z][r]-sum[z][l-1])

    整理为

    sum[x][r]-sum[z][r]-(sum[x][l-1]-sum[z][l-1])

    我们已知x和sum[x][r],对于z我们枚举,

    对于sum[x][l-1]-sum[z][l-1]我们需要一个最小的

    用minv[x][y]表示sum[x]-sum[y]的最小值。

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<vector>
    
    using namespace std;
    
    const int maxn=1000010;
    
    int n,ans,p[26][26],minv[26][26],sum[26],last[26];
    
    char s[maxn];
    
    int main()
    {
        scanf("%d",&n);
        scanf("%s",s+1);
        for (int a=1;a<=n;a++)
        {
            int c=s[a]-'a';
            sum[c]++;
            last[c]=a;
            for (int b=0;b<26;b++)
                if (b!=c && sum[b]) ans=max(ans,max(sum[c]-sum[b]-minv[c][b]-(last[b]==p[c][b]),sum[b]-sum[c]-minv[b][c]-(last[b]==p[b][c])));
            for (int b=0;b<26;b++)
            {
                if (sum[c]-sum[b]<minv[c][b]) minv[c][b]=sum[c]-sum[b],p[c][b]=a;
                if (sum[b]-sum[c]<minv[b][c]) minv[b][c]=sum[b]-sum[c],p[b][c]=a;
            }
        }
        printf("%d
    ",ans);
    
        return 0;
    }
    AC

    如果视线和障碍物有公共点,那么我们认为视线会被阻挡,无法看见。

    如果视线和镜子有公共点,那么我们认为发生了反射。反射的过程遵

    循物理规律——入射角等于反射角,且反射光线与入射光线在镜子同

    侧。也就是说,想要看见对方,Hja 和 Yjq 必须在镜子的同一侧,

    包括镜子所在直线上(参见样例 1) 。如果视线与镜子重合, 那

    么不会发生反射, 并且镜子不被当作障碍物 (参见样例 4) 。Hja

    很想知道他站在原地能否看见 Yjq,帮助他解决这个问题。

    【输入格式】


    【输出格式】
    如果 Hja 站在原地能看到 Yjq,则输出"YES",否则输出"NO"。
    【样例输入 1】
    -1 3
    1 3
    0 2 0 4
    0 0 0 1
    【样例输出 1】
    NO
    【样例输入 2】
    0 0
    1 1
    0 1 1 0
    -100 -100 -101 -101
    【样例输出 2】
    NO
    【样例输入 3】
    0 0
    1 1
    0 1 1 0
    -1 1 1 3
    【样例输出 3】
    YES
    【样例输入 4】
    0 0
    10 0
    100 100 101 101
    1 0 3 0
    【样例输出 4】
    YES
    【数据规模与约定】
    对于100%的数据,所有坐标均为绝对值不超过10 4 的整数。

    输入的线段不会退化成点,且两条线段没有交点。Hja 和

    Yjq 的位置不同,且不在任何一条线段上。

    题解:计算几何 弃疗

    代码:

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const double eps=1e-8;
    int sgn(double a)
    {
        if (fabs(a)<eps) return 0;
        else
        {
            if (a>0.0) return 1;
            else return -1;
        }
    }
    struct point
    {
        double x,y;
        point(){}
        point(double a,double b)
        {
            x=a;y=b;
        }
        void init()
        {
            scanf("%lf%lf",&x,&y);
        }
        point operator+(const point &a)const
        {
            point ans;
            ans.x=x+a.x;
            ans.y=y+a.y;
            return ans;
        }
        point operator-(const point &a)const
        {
            point ans;
            ans.x=x-a.x;
            ans.y=y-a.y;
            return ans;
        }
        point operator*(const double &a)const
        {
            point ans;
            ans.x=x*a;
            ans.y=y*a;
            return ans;
        }
        void print()
        {
            printf("%lf %lf
    ",x,y);
        }
    }v,p,w1,w2,m1,m2;
    double cross(point a,point b)
    {
        return a.x*b.y-a.y*b.x;
    }
    double dot(point a,point b)
    {
        return a.x*b.x+a.y*b.y;
    }
    bool cross(point p1,point p2,point p3,point p4)
    {
        if (sgn(cross(p2-p1,p3-p1))*sgn(cross(p2-p1,p4-p1))==1) return false;
        if (sgn(cross(p4-p3,p1-p3))*sgn(cross(p4-p3,p2-p3))==1) return false;
        if (sgn(max(p1.x,p2.x)-min(p3.x,p4.x))==-1) return false;
        if (sgn(max(p1.y,p2.y)-min(p3.y,p4.y))==-1) return false;
        if (sgn(max(p3.x,p4.x)-min(p1.x,p2.x))==-1) return false;
        if (sgn(max(p3.y,p4.y)-min(p1.y,p2.y))==-1) return false;
        return true;
    }
    point getcross(point p1,point p2,point p3,point p4)
    {
        double a=p2.y-p1.y;
        double b=p1.x-p2.x;
        double c=-p1.x*p2.y+p1.y*p2.x;
        double d=p4.y-p3.y;
        double e=p3.x-p4.x;
        double f=-p3.x*p4.y+p3.y*p4.x;
        double x=(b*f-c*e)/(a*e-b*d);
        double y=(a*f-c*d)/(b*d-a*e);
        return point(x,y);
    }
    point calcfoot(point p1,point p2,point p3)
    {
        double ratio=dot(p1-p2,p3-p2)/dot(p3-p2,p3-p2);
        return p2+(p3-p2)*ratio;
    }
    bool check()
    {
        if (!cross(v,p,w1,w2))
        {
            if (!cross(v,p,m1,m2)) return true;
            if (sgn(cross(m1-v,m2-v))==0 && sgn(cross(m1-p,m2-p)==0)) return true;      
        }
        if (sgn(cross(m2-m1,v-m1))*sgn(cross(m2-m1,p-m1))==1)
        {
            point foot=calcfoot(p,m1,m2);
            foot=foot*2.0-p;
            if (cross(v,foot,m1,m2))
            {
                foot=getcross(v,foot,m1,m2);
                if (!cross(v,foot,w1,w2) && !cross(foot,p,w1,w2)) return true;
            }
        }
        return false;
    }
    int main()
    {
        freopen("b.in","r",stdin);
        freopen("b.out","w",stdout);
        v.init();
        p.init();
        w1.init();
        w2.init();
        m1.init();
        m2.init();
        if (check()) printf("YES
    ");
        else printf("NO
    ");
        return 0;
    }
    AC

    c
    【问题描述】
    你是能看到第三题的 friends 呢。
    ——aoao
    众所周知,八数码问题是一个非常难的问题,但是Yjq 非常有

    面子,他把这道题简化了一番。 现在给了你一个3 × 3的方格

    图, 你的目标是通过不断移动使得相邻颜色的块形成联通块。

    你每次的移动方式是选择一列或者一行进行置换滑动

    (这个解释起来比较麻烦,看下面的图就懂了) 。所谓置换滑动,

    就是所有格子沿着给定的方向顺次移动, 最后一个格子会被置换

    到最前面的过程。 现在给定整个方格图,以及每个格子是否能够

    移动,求使得相同颜色联通的最小步数。

    【输入格式】
    输入为3 × 3的方格图,每个位置由五个字符组成,前四个字符分别

    表示上下左右四个部分的颜色, 第五个字符表示该格子是否能够移

    动, 其中0是能移动1是不能移动。

    【输出格式】
    一行一个整数代表答案。

    题解:爆搜

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<queue>
    
    using namespace std;
    
    #define get(a,b,c) ((a-1)*12+(b-1)*4+c)
    
    int en,tmp[4][4],color[37],map[9][5],q[37],nowmap[4][4],newmap[4][4];
    
    bool num[9],use[90000000],right[37],row[4],col[4],col_find[5];
    
    char s[10];
    
    struct rec
    {
        int sta,step;
        rec(){}
        rec(int a,int b)
        {
            sta=a;step=b;
        }
    };
    
    queue<rec> que;
    
    struct edge
    {
        int e;
        edge *next;
    }*v[37],ed[100];
    
    void add_edge(int s,int e)
    {
        en++;
        ed[en].next=v[s];v[s]=ed+en;v[s]->e=e;
        en++;
        ed[en].next=v[e];v[e]=ed+en;v[e]->e=s;
    }
    
    bool check(int nows)
    {
        memset(num,false,sizeof(num));
        for (int a=3;a>=1;a--)
            for (int b=3;b>=1;b--)
                if (a!=3 || b!=3)
                {
                    tmp[a][b]=nows%10;
                    num[nows%10]=true;
                    nows/=10;
                }
        for (int a=0;a<9;a++)
            if (!num[a])
            {
                tmp[3][3]=a;
                break;
            }
        int cnt=0;
        for (int a=1;a<=3;a++)
            for (int b=1;b<=3;b++)
                for (int c=1;c<=4;c++)
                {
                    cnt++;
                    color[cnt]=map[tmp[a][b]][c];
                }
        memset(right,false,sizeof(right));
        memset(col_find,false,sizeof(col_find));
        for (int a=1;a<=36;a++)
            if (!right[a])
            {
                if (col_find[color[a]]) return false;
                col_find[color[a]]=true;
                int front=1,tail=1;
                q[1]=a;
                right[a]=true;
                for (;front<=tail;)
                {
                    int now=q[front++];
                    for (edge *e=v[now];e;e=e->next)
                        if (color[e->e]==color[now] && !right[e->e])
                        {
                            right[e->e]=true;
                            q[++tail]=e->e;
                        }
                }
            }
        return true;
    }
    
    int main()
    {
        freopen("c.in","r",stdin);
        freopen("c.out","w",stdout);
    
        for (int a=1;a<=3;a++)
            for (int b=1;b<=3;b++)
            {
                add_edge(get(a,b,1),get(a,b,3));
                add_edge(get(a,b,1),get(a,b,4));
                add_edge(get(a,b,2),get(a,b,3));
                add_edge(get(a,b,2),get(a,b,4));
                if (a!=3) add_edge(get(a,b,2),get(a+1,b,1));
                if (b!=3) add_edge(get(a,b,4),get(a,b+1,3));
            }
        int cnt=0;
        for (int a=1;a<=3;a++)
            for (int b=1;b<=3;b++)
            {
                scanf("%s",s+1);
                for (int c=1;c<=4;c++)
                    if (s[c]=='R') map[cnt][c]=0;
                    else 
                    {
                        if (s[c]=='G') map[cnt][c]=1;
                        else
                        {
                            if (s[c]=='B') map[cnt][c]=2;
                            else map[cnt][c]=3;
                        }
                    }
                if (s[5]=='1') row[a]=col[b]=true;
                cnt++;
            }
        int nows=1234567;
        if (check(nows))
        {
            printf("0
    ");
            return 0;
        }
        que.push(rec(nows,0));
        use[nows]=true;
        rec now;
        while (que.size())
        {
            now=que.front();
            que.pop();
            int step=now.step;
            int nows=now.sta;
            memset(num,false,sizeof(num));
            for (int a=3;a>=1;a--)
                for (int b=3;b>=1;b--)
                    if (a!=3 || b!=3)
                    {
                        nowmap[a][b]=nows%10;
                        num[nows%10]=true;
                        nows/=10;
                    }
            for (int a=0;a<9;a++)
                if (!num[a])
                {
                    nowmap[3][3]=a;
                    break;
                }
            int news=0;
            for (int a=1;a<=3;a++)
            {
                if (!row[a])
                {
                    for (int b=1;b<=3;b++)
                        for (int c=1;c<=3;c++)
                            newmap[b][c]=nowmap[b][c];
                    int x=newmap[a][1];
                    newmap[a][1]=newmap[a][2];newmap[a][2]=newmap[a][3];newmap[a][3]=x;
                    news=0;
                    for (int b=1;b<=3;b++)
                        for (int c=1;c<=3;c++)
                            if (b!=3 || c!=3) news=news*10+newmap[b][c];
                    if (!use[news])
                    {
                        use[news]=true;
                        if (check(news))
                        {
                            printf("%d
    ",step+1);
                            return 0;
                        }
                        que.push(rec(news,step+1));
                    }
                    x=newmap[a][1];
                    newmap[a][1]=newmap[a][2];newmap[a][2]=newmap[a][3];newmap[a][3]=x;
                    news=0;
                    for (int b=1;b<=3;b++)
                        for (int c=1;c<=3;c++)
                            if (b!=3 || c!=3) news=news*10+newmap[b][c];
                    if (!use[news])
                    {
                        use[news]=true;
                        if (check(news))
                        {
                            printf("%d
    ",step+1);
                            return 0;
                        }
                        que.push(rec(news,step+1));
                    }
                }
                if (!col[a])
                {
                    for (int b=1;b<=3;b++)
                        for (int c=1;c<=3;c++)
                            newmap[b][c]=nowmap[b][c];
                    int x=newmap[1][a];
                    newmap[1][a]=newmap[2][a];newmap[2][a]=newmap[3][a];newmap[3][a]=x;
                    news=0;
                    for (int b=1;b<=3;b++)
                        for (int c=1;c<=3;c++)
                            if (b!=3 || c!=3) news=news*10+newmap[b][c];
                    if (!use[news])
                    {
                        use[news]=true;
                        if (check(news))
                        {
                            printf("%d
    ",step+1);
                            return 0;
                        }
                        que.push(rec(news,step+1));
                    }
                    x=newmap[1][a];
                    newmap[1][a]=newmap[2][a];newmap[2][a]=newmap[3][a];newmap[3][a]=x;
                    news=0;
                    for (int b=1;b<=3;b++)
                        for (int c=1;c<=3;c++)
                            if (b!=3 || c!=3) news=news*10+newmap[b][c];
                    if (!use[news])
                    {
                        use[news]=true;
                        if (check(news))
                        {
                            printf("%d
    ",step+1);
                            return 0;
                        }
                        que.push(rec(news,step+1));
                    }
                }
            }
        }
    
        return 0;
    }
    AC
  • 相关阅读:
    Eclipse扩展安装插件方式
    Tomcat通过JNDI方式链接MySql数据库
    ArrayList实现根据某属性大小相间排序
    JMeter 怎么保存登录状态
    JMeter怎么使用代理服务器
    JMeter模拟多个用户进行登录
    JMeter怎么在get URL请求、POST请求中添加动态参数用于服务器段安全验证
    (转)sizeof()和_countof()区别
    潜心修炼, 生活,会给你一个惊喜~
    最初的梦想
  • 原文地址:https://www.cnblogs.com/zzyh/p/7617632.html
Copyright © 2011-2022 走看看