2016-8-4夏令营入营测试总结

来源:互联网 发布:mac西柚色口红专柜价格 编辑:程序博客网 时间:2024/06/06 05:10

本次的测试从思维和编程角度上来说都是很简单的,然而在时间上却并不简单。虽然说我们现在的水平已经相当不错,但是考的仍然不是很好,估计是久离算法的缘故了。

题目的链接是http://pan.baidu.com/s/1hrIQMry。
【T1:音阶】
这题很水,直接做吧,只不过要注意题目中是“最后一个音符”而不是“最后一节的重音”。

/*A MT : A D EC MT : C F G*/# include <cstdio># include <cstring>using namespace std;const int MAXL = 120;char music[MAXL];int A_MT,C_MT;int main(){    freopen("ljestvica.in","r",stdin);    freopen("ljestvica.out","w",stdout);    scanf("%s",music);    int len = strlen(music);    bool nowisFirst = true;    A_MT = C_MT = 0;    for (int i=0;i<len;++i){        if (nowisFirst){            if (music[i] == 'A' || music[i] == 'D' || music[i] == 'E') ++A_MT;            if (music[i] == 'C' || music[i] == 'F' || music[i] == 'G') ++C_MT;        }        if (music[i] == '|') nowisFirst = true;        else nowisFirst = false;    }    if (A_MT == C_MT)        if (music[len-1] == 'C' || music[len-1] == 'F' || music[len-1] == 'G')            printf("C-dur");        else printf("A-mol");    else if (A_MT > C_MT) printf("A-mol");    else printf("C-dur");    return 0;}

【T2:波老师】
真是奇怪的题目……好吧这题有个很简单的暴力,就是O(n2)的,但是用一点常数的优化就多过了20%的数据……那数据的范围可是从1000106啊……好吧不吐槽出题人了,先放程序:

# include <algorithm># include <cstring># include <cstdio># include <cmath>using namespace std;const int MAXN = 2000010;pair<int,int> Point[MAXN];int T;int n,m;/*Water!*///int MLen[MAXN*MAXN];bool f[MAXN];bool found;//int size = 0;int main(){    freopen("teacher.in","r",stdin);    freopen("teacher.out","w",stdout);    scanf("%d",&T);    for (int kase = 0 ; kase < T ; ++kase){        /*Initial*/        memset(f,false,sizeof(f));    //  size = 0;        scanf("%d%d",&n,&m);        for (int i=0;i<n;++i){            scanf("%d%d",&Point[i].first,&Point[i].second);        }        sort(Point+0,Point+n);        /*Water!*/        found = false;        for (int i=0;i<n;++i){            for (int j=0;j<i;++j){                int dis = abs(Point[i].first-Point[j].first)+abs(Point[i].second-Point[j].second);                if (f[dis]){                    found = true;                    break;                }                else f[dis] = true;            }        }        /*        bool found = false;        sort(MLen+0,MLen+size);        for (int i=1;i<size;++i){            if (MLen[i] == MLen[i-1]){                found = true;            }        }        */        if (found) printf("YES\n");        else printf("NO\n");    }    return 0;}

好吧另外补一下,其实这其中有用到鸽巢原理的……考虑到,其实只有最多2×106种的不相同的曼哈顿距离,所以这个break就使得时间复杂度变成了O(min(n2,2×m))!确实,有是一个break就有神效。

【T3:爆裂吧世界】
先吐槽一下名字~出题人没有改过来吧。好吧,这题的思维难度比较大,而我是在临考试结束前十几分钟时想出来的,根本没有时间编了~然而我的想法和出题人的一样……
好吧不说废话了,这道题目题面已经足够明晰,那么对于其的做法,我们先要参考一下逆序对的树状数组解法,在这里我们可以知道如何求出在第i个数前面并且比第i个数小的数的个数了,而且以此类推还可以求出在第i个数后面的那些啊,比第i个数小的那些啊……
总之很简单。那么我们考虑一下这个能干什么。考虑将这个四元组(a,b,c,d)分成两个双元组(a,b)(c,d),然后我们统计第i个数分别作为其中的abcd,并分别求方案数。那么,我们先想想看,如果我们求出两个双元组各自的方案数,再乘起来,得到的是答案吗?显然不是,因为题目要求abcd,但是直接应用乘法原理很有可能会使得不等号不成立。那么怎么办呢?减掉等于的部分!怎么减呢?容斥原理!先考虑没有限制的,就是乘法原理直接乘,然后有两个互相相等的有6种情况,但是可以排除掉两种,a=bc=d,因为本身我们求方案数的时候就没有这两种情况。同理,三个和四个互相相等的都一定会有这种情况,所以都会排除。如果用P{...}来表示相应的方案数,那么有

P{abcd}=P{a?b?c?d}P{a=c}P{a=d}P{b=c}P{b=d}

然后相应求出来就好了。怎么求呢?这里以P{a=c}为例,如果a=c,那么我们现在要的就是先枚举一个i,然后统计另外独立存在的bd,也就是分别将i作为ac,统计相应的(i,b)(i,d)的方案数,由于其独立存在,所以用乘法原理乘起来就好了。像(i,b)的方案数实际上就是在第i个数后面并且比第i个数大的数的个数,其余以此类推,我们就可以求出P{a=c}=i=1nP{i,b}×P{i,d},其余的几个也可以用类似的方法求出。
于是便求完了,代码如下:

/*目前并没有写完,稍后补上*/

其实这道题并不难,只是代码量有点大,不是那种能在5分钟内编完的类型……

1 0