zoukankan      html  css  js  c++  java
  • 20170903校内训练

    卡片(card)

    【题目描述】

           lrb喜欢玩卡牌。他手上现在有n张牌,每张牌的颜色为红绿蓝中的一种。现在他有两种操作。一是可以将两张任意位置的不同色的牌换成一张第三种颜色的牌;二是可以将任意位置的两张相同颜色的牌换成一张该颜色的牌。两个操作后都可以将生成的牌放到任意位置。现在他想知道,最后一张牌可能是什么颜色的。

    【输入描述】

           第一行输入一个,表示卡牌数量。

           第二行输入一个由’B’,’G’,’R’组成的长度为n的字符串,分别表示卡牌的颜色为蓝色、绿色、红色中的一种。

    【输出描述】

           输出’B’,’G’,’R’中的若干个字母,按字典序输出。代表可能的最后一张牌的颜色。

    【样例】

    输入1

    输出1

    2

    RB

    G

    输入2

    输出2

    3

    GRG

    BR

    输入3

    输出3

    4

    BBBB

    B

    【数据范围】

    对于100%的数据,n<=200

    16个if。。。

    首先如果只有某种颜色,那么剩下的必然只有这种颜色。

    其次如果只有两张牌,那么直接判断出另一张牌即可。

    剩下的情况,如果某种颜色没牌,另一种颜色只有一张牌,那么最后剩下的为这两种颜色。

    除了以上的情况,剩下三种牌都有可能。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    char c[1000];int r=0,g=0,b=0;
    int main()
    {
        //freopen("card.in","r",stdin);freopen("card.out","w",stdout);
        int n;scanf("%d",&n);
        if(n==0){return 0;}
        scanf("%s",c);
        for(int i=0;i<n;i++)
        {
            if(c[i]=='R')r++;
            if(c[i]=='G')g++;
            if(c[i]=='B')b++;
        }
        if(r>=1&&g>=1&&b>=1)puts("BGR");
        else if(r>=2&&g>=2)puts("BGR");
        else if(r>=2&&b>=2)puts("BGR");
        else if(g>=2&&b>=2)puts("BGR");
        else if(r>=2&&g>=1)puts("BG");
        else if(r>=2&&b>=1)puts("BG");
        else if(g>=2&&r>=1)puts("BR");
        else if(g>=2&&b>=1)puts("BR");
        else if(b>=2&&r>=1)puts("GR");
        else if(b>=2&&g>=1)puts("GR");
        else if(b>=1&&g>=1)puts("R");
        else if(b>=1&&r>=1)puts("G");
        else if(g>=1&&r>=1)puts("B");
        else if(b>=1)puts("B");
        else if(g>=1)puts("G");
        else if(r>=1)puts("R");
        return 0;
    }
    View Code

    取数(win)

    【题目描述】

           lrb目前有n个数字,他想知道这n个数中选出若干个数,平均数减中位数的最大值是多少。可以证明,对于一个递增数列a,如果是平均数aw减中位数最大时的中位数,l表示在w两边分别取相邻数字的数量,f(w,l)表示以aw为中位数,在w两侧各取相邻l个数时平均数减中位数的值,那么f(w,l)为关于l的单峰函数。

    【输入描述】

    第一行为n,为数字个数。

    第二行有n个数,分别代表n个数字。

    【输出描述】

           输出一个数,为平均数减中位数的最大值,保留两位小数。

    【样例】

    输入

    输出

    4

    1 2 3 4

    0.33

    【数据范围】

    对于60%数据,n<=21

    对于75%的数据,n<=2000

    对于100%的数据,n<=10^5,0<=ai<=10^6

    排序,首先取奇数个数显然不会比取偶数个数劣。证明:设中间两个数为x1,x2(x1<x2),其它数的总和为x3,总个数为n,我们可以通过删除x2使得结果不劣

    设S1为删除前平均数-中位数,S2为删除后平均数-中位数,则S1=(x1+x2+x3)/n-(x1+x2),S2=(x1+x3)/(n-1)-x1

    S2-S1=(nx1+xn3-(n-1)x1-(n-1)x2-(n-1)x3)/(n(n-1))-x1+x1+x2

              =(x1-nx2+x2+x3+n(n-1)x2)/(n(n-1))

              =(x1+x3+x2(n^2-2n+1))/(n(n-1))

              =(x1+(n-1)^2*x2+x3)/(n(n-1))

    因为x1+(n-1)^2*x2+x3>=0,(n(n-1))>0  (因为n>=2)

    所以S2-S1>=0,S2>=S1,所以取奇数个数

    我们取的数一定是如下图所示(黑圈是中位数,黑线是取的数,红线是题目给出的数据)

    如果不这么取,那么平均数会变小。我们可以枚举中位数。为了快速算出黑线的数的总和,我们需要前缀和

    设两条黑线长度都为L(即取L个数),f(L)为上图黑线和黑圈的平均数

    因为总是有一个临界值(设取了x个数),使得再取第(x+1)个数对平均数的贡献为负数(因为数据单调不降(之前排好序了))

    所以f(L)是一个上单峰函数,我们可以通过三分法求得f(L)的峰值

    由于这道题的所有数加起来会爆int,所以我们要用long long

    这样,我们可以在O(nlog(n))的时间内解决

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int a[100101];long long b[100101];double ans=-1.0;int n;
    double f(int x,int l)//求以x为中位数,l为黑线长度的平均数减中位数的值
    {
        return (double)(b[x]-b[x-l-1]+b[n]-b[n-l])/(l*2+1)-a[x];
    }
    int main()
    {
        //freopen("win.in","r",stdin);freopen("win.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        for(int i=1;i<=n;i++)b[i]=b[i-1]+a[i];
        for(int i=1;i<=n;i++)
        {
            int l=0,r=min(i-1,n-i),o;long long Max=-1ll;
            while(1)
            {
                if(r-l<5)
                {
                    for(int j=l;j<=r;j++)ans=max(ans,f(i,j));
                    break;
                }
                int lm=l+(r-l)/3,rm=r-(r-l)/3;
                if(f(i,lm)<f(i,rm))l=lm;
                else r=rm;
            } 
        }
        printf("%.2lf",ans);
        return 0;
    }
    View Code

    密码(key)

    【题目描述】

           lrb去柜员机取钱,并输入了他的四位密码。但是这一切都被一个黑帮拍摄了下来。幸好,这一次他的银行卡里并没有剩余任何钱。lrb知道了他的账户被异常登录后十分害怕,然后修改了他的密码。从此以后他为了不被看出密码,他开始“徐晃”。但这一切还是被拍摄了下来,拍摄多次以后,这个黑帮找到了你,希望你在一秒内帮他算出lrb的可能使用的密码数量。

    【输入描述】

           第一行输入一个n,为lrb被拍摄的动作次数。

           接下来n行,每行第一个数为t,表示lrb接下来的手指移动次数,接下来为一个长度为t的数字串,表示lrb手指经过的轨迹。lrb手指经过的位置,可能没有按,也有可能按了多次。

    【输出描述】

           输出一行,为可能的密码数量。

    【样例】

    输入

    输出

    2

    3 123

    3 234

    5

    解释

    lrb可能用的是2222,2223,2233,2333,3333五种密码

    【数据范围】

    设所有轨迹串的总长度为L。

    对于35%的数据,L<=5000

    对于100%的数据,1<=n<=1000,1<=t<=10^4,L<=10^6

    首先可以在O(10L)的时间内预处理出对于每一位向后的第一个某个数字的位置。我们可以把轨迹串拼在一起

    用f[i][j]表示从第i个位置(包括i(因为可以多次按同一个键))向后查找j数(0~9)的位置,不存在设为1000001,再令f[1000001][0~9]=10000001

    然后就可以暴力枚举每种密码后用的O(n)时间进行check,从第0号位置开始。用f[0][第一位的数]跳到下一个位置,接着用f[刚刚跳到的位置][第二位的数]继续跳,以此类推。

    最后把结果不是1500000的统计进答案即可。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    char c[1000010];int t[1000010],f[1000010][10],ans=0;
    int main()
    {
    //    freopen("key.in","r",stdin);freopen("key.out","w",stdout);
        int n;scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%s",&t[i],c+t[i-1]);t[i]+=t[i-1];
        }
        for(int i=0;i<=9;i++)f[1000001][i]=1000001;
        for(int i=n;i>=1;i--)
        for(int j=t[i]-1;j>=t[i-1];j--)
            if(j==t[i]-1)
            {
                for(int k=0;k<=9;k++)f[j][k]=1000001;
                f[j][c[j]-'0']=j;
            }
            else
            {
                for(int k=0;k<=9;k++)f[j][k]=f[j+1][k];
                f[j][c[j]-'0']=j;
            }
        for(int a=0;a<=9;a++)
        for(int b=0;b<=9;b++)
        for(int c=0;c<=9;c++)
        for(int d=0;d<=9;d++)
        {
            bool ok=1;
            for(int i=1;i<=n;i++)
            {
                if(f[f[f[f[t[i-1]][a]][b]][c]][d]==1000001){ok=0;break;}
            }
            if(ok)ans++;
        }
        printf("%d",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    GDB编辑、搜索源码以及在线帮助
    GDB查看栈信息
    GDB信号处理
    GDB反向调试
    GDB调试多进程程序
    GDB后台调试命令
    GDB non-stop模式
    GDB调试多线程程序
    GDB禁用删除断点
    解决Mac OS下Eclipse、IntelliJ IDEA打开其他窗口默认全屏
  • 原文地址:https://www.cnblogs.com/lher/p/7471019.html
Copyright © 2011-2022 走看看