2011百校联动“菜鸟杯”程序设计公开赛(现更新5道)

来源:互联网 发布:mac下载flash好慢 编辑:程序博客网 时间:2024/05/19 20:56

作为一个真正意义上的菜鸟,A掉了4题。。。。。

比赛暴漏了很多问题,最大的就是代码控制能力不强,很多简单的题不能在很短的时间内敲出来,说明还是打的少。以后尽量少看别人代码,争取通过自己的思考做题,这样碰到同类的题才能迅速A掉。

下面是我做出来的5道题的简单分析:

其中的1002、1005、1008都是真正意义上的水题。

1002:

每5个字符转换一次,遇到字母就是0,遇到数字就是1,然后得出这5个数字对应的10进制数字,对应到26个英文字母就是答案。

代码如下:

#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<iostream>#include<algorithm>#include<vector>#include<queue>#include<stack>#include<map>#include<set>using namespace std;#define max(a, b) a > b ? a : b#define min (a, b) a < b ? a : b#pragma comment(linker, "/STACK:102400000,102400000")char ans[26] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};int main(){    int len;    char str[10010];    int sum;    while(scanf("%d", &len) != EOF)    {        scanf("%s", str);        for(int i = 0; i < len; i += 5)        {            sum = 0;            for(int j = i; j < i + 5; ++j)            {                if(str[j] >= '0' && str[j] <= '9')                    sum += pow(2.0, 4 - j % 5);            }            printf("%c", ans[sum]);        }        printf("\n");    }    return 0;}

1005:

KFC排队问题,简单的数学问题。读清楚题就可以迅速A掉。

代码如下:

#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<iostream>#include<algorithm>#include<vector>#include<queue>#include<stack>#include<map>#include<set>using namespace std;int b, d, f, p;char que[10010];int sum(char a){    if(a == 'A')        return (b + d + f);    else if(a == 'B')        return (2 * b + 2 * d + p);    else        return (3 * b + 3 * d + 2 * p);}int main(){    int n;    int ans, len, mincost;    while(scanf("%d%d%d%d%d", &n, &b, &d, &f, &p) != EOF)    {        mincost = 9999999;        for(int k = 0; k < n; ++k)        {            scanf("%s", que);            len = strlen(que);            ans = 0;            for(int i = 0; i < len; ++i)                ans += sum(que[i]);            if(mincost > ans)            mincost = ans;        }        printf("%d\n", mincost);    }    return 0;}
1008:

比较2个字符串,看看主串中含有多少个不重叠的子串,开始以为是KMP,发现很多人迅速水过,想着应该是纯暴力啊。。。KMP可不是一时半会就可以理解的。于是果断暴力,果断A掉了。。。

代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;char s[1000050], p[10];int main(){    int ncase;    int lens, lenp;    int i, j, k, sign;    int sum;    scanf("%d", &ncase);    while(ncase--)    {        scanf("%s%s", s, p);        lens = strlen(s);        lenp = strlen(p);        sum = 0;        for(i = 0; i < lens; ++i)        {            int k = i;            for(j = 0; j < lenp; ++j)            {                if(s[k] == p[j])                    k++;                else                    break;            }            if(j == lenp)            {                sum++;                i += lenp - 1;            }        }        printf("%d\n", sum);    }    return 0;}
1001和1006是比较难的。其中1006是比赛后A的。。。

1001:

可以把式子分解为:(y-x)(y+x)=n,设y-x=a,y+x=b.然后通过枚举得出结果。但是TLE了。后来听数学系的同学给了一点思路,发现通过均值不等式可以大大减少枚举的个数,通过对num开平方,从中间开始向下找因子,找到的第一个肯定就是x的最小值(x=(a-b)/2),a-b的值越小,说明ab越接近,这点均值不等式可以说明。所以做法就是先对num开平方,得到temp,然后从temp向下枚举,找到的第一个a,b就是答案。但是需要注意的是x是正整数,所以a和b不能相等。相等x=0,这点注意一下就可以了。

代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;int main(){    int ncase;    int num, temp;    bool flag;    scanf("%d", &ncase);    while(ncase--)    {        scanf("%d", &num);        flag = false;        temp = (int)sqrt(num * 1.0);        for(int i = temp; i >= 1; --i)        {            if(num % i != 0)                continue;            else            {                if((i + num / i) % 2 == 0 && i != num / i)                {                    printf("%d\n", (num / i - i) / 2);                    flag = true;                    break;                }            }        }        if(!flag)            printf("-1\n");    }    return 0;}
1006:

这道题确实是一个难度很大的找规律题,后来发现matrix67大神博客上有这个数列的介绍,只要看下这篇博客就应该能搞定了。其实就是一个简单的模拟而已。

就是判断上一个数列的1,2,3的个数,比如1221,则从左向右遍历,发现有1个1,所以是“11”,然后有2个2,所以加上“22”,变成“1122”,然后是1个1,加上“11”,成为“112211”。其实就是判断数列从左到右重复数字出现的个数。

文章链接:http://www.matrix67.com/blog/archives/3870/comment-page-1

代码如下:

#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<iostream>#include<algorithm>#include<vector>#include<queue>#include<stack>#include<map>#include<set>using namespace std;int p[32] = {0, 1, 2, 2, 4};string s[32] = {"", "1", "11", "21", "1211"};void fast(int n){    int len = s[n - 1].length();    int sum = 1;    for(int i = 0; i < len - 1; ++i)    {        if(s[n - 1][i] != s[n - 1][i + 1])        {            if(i == len - 2)            {                s[n] += (sum + '0');                s[n] += s[n - 1][i];                s[n] += '1';                s[n] += s[n - 1][i + 1];            }            else            {                s[n] += (sum + '0');                s[n] += s[n - 1][i];                sum = 1;            }        }        else        {            sum++;            if(i == len - 2)            {                s[n] += (sum + '0');                s[n] += s[n - 1][i];                break;            }        }    }    p[n] = s[n].length();}int main(){    int n;    for(int i = 5; i <= 30; ++i)        fast(i);    while(scanf("%d", &n) && n)    {        printf("%d\n", p[n]);    }    return 0;}//打表~#include<cstdio>int main(){int n;int p[30] = {1, 2, 2, 4, 6, 6, 8, 10, 14, 20, 26, 34, 46, 62, 78, 102, 134, 176, 226, 302, 408, 528, 678, 904, 1182, 1540, 2012, 2606, 3410, 4462};while(scanf("%d", &n), n)printf("%d\n", p[n - 1]);return 0;}

原创粉丝点击