我要成为一名优秀的数据科学家程序员数据结构和算法分析

acmer之路(2)三月第四周日志

2018-04-01  本文已影响45人  跌跌撞撞小红豆

这周比较繁忙,周一到周四课比较多,周五为了准备中科院软件园的一个面试早上五点多就起床赶公交,周天又参加了院里的一场足球赛。在这周里,我一共只写了十道题,现在贴出来和大家分享一下。


三月第四周.png

ID 2004

#include<stdio.h>

int main()
{
    int grade;
    
    while (scanf("%d", &grade) != EOF)
    {
        if (grade < 0 || grade>100)
        {
            printf("Score is error!\n");
        }
        else 
        {
            grade = grade / 10;
            switch (grade)
            {
            case 10:
            case 9:    printf("A\n"); break;
            case 8:    printf("B\n"); break;
            case 7:    printf("C\n"); break;
            case 6:    printf("D\n"); break;
            default:    printf("E\n"); break;
            }
        }
    }
    return 0;
}

这一题很简单,不过初学者容易忘记switch语句的规范。switch括号里面的数据类型和case后面的数据类型一定要对应。

ID 2005

#include<stdio.h>

int main() {
    int a, b, c;
    int day;
    day = 0;
    int i,j;
    int d[13] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int k[13] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    while (~scanf("%d/%d/%d", &a, &b, &c))
    {
        if (a % 400 == 0 || (a % 4 == 0 && a % 100 != 0))
        {
            if (b == 1)
            {
                printf("%d\n", c);
            }
            else
            {
                for (i = 0; i <= (b - 1); i++)
                {
                    if(i == b - 1)
                    {
                        day = day + c;
                        printf("%d\n", day); break;
                    }
                    day = day + k[i];
                }
                day = 0;
            }
        }
        else 
        {
            if (b == 1)
            {
                printf("%d\n", c);
            }
            else
            {
                for (j = 0; j <= (b - 1); j++)
                {
                    if (j == b - 1)
                    {
                        day = day + c;
                        printf("%d\n", day); break;
                    }
                    day = day + d[j];
                }
                day = 0;
            }
        }
    }
    return 0;
}

这一题我当时是提交了好几遍才AC的,而且个人认为我的逻辑有些繁杂。因为闰年与平年的二月天数有区别,我单独设置了两个数组分别来存放闰年与平年。先判断是不是闰年,是就用第一个数组来累加,否就用第二数组来累加。很明显,我第二个数组的设置是多余的,后来看了网上很多人的实现更觉得是个累赘。当时为了图懒省事,索性一刀切弄了两个数组。

ID 2006

#include<stdio.h>

int main() 
{    
    int n;
    int i;
    int a[50];
    int product;
    product = 1;
    while (scanf("%d", &n) != EOF)
    {
        for (i = 0; i < n; i++)
        {
            scanf("%d", &a[i]);
            
            if (a[i] % 2 != 0)
            {
                product = product * a[i];
            }
            
        }
        printf("%d\n", product);
        product = 1;
    }
    return 0;
}

ID 2007

#include<stdio.h>

int main() 
{    
    int a, b;
    int i, j;
    int product1, product2;
    product1 = 0;
    product2 = 0;
    int temp;
    while (scanf("%d %d", &a, &b) != EOF)
    {
        if (a > b) 
        {     
            temp = a; 
            a = b; 
            b = temp;
        }
        for (i = a; i <= b; i++)
        {
            if (i % 2 == 0)
            {
                product1 = product1 + i * i;
            }
        }
            
        for (j = a; j <= b; j++)
        {
            if (j % 2 != 0)
            {
                product2 = product2 + j * j*j;
            }
        }
            
    
        printf("%d %d\n", product1, product2);
        product1 = 0;
        product2 = 0;
    }
    
    return 0;
}

这题有两个地方需要注意。其一要判断输入的两个值的大小关系,这个我一开始忽略了怎么都不通过。其二要注意输出的乘积在最后的置零,值的累积会让后面的输出都错误。

ID 2018

#include<stdio.h>
int main()
{
    int n;
    int count;
    int temp;
    int age[4] = { 0, 0, 0, 0 };
    int i;
    while (scanf("%d", &n),n)
    {
        if (n == 1)
        {
            age[3] = 1;
            printf("%d\n", age[3]);
        }
        else
        {
            age[3] = 1; 
            age[2] = age[1] = 0;
            for (i = 2; i <= n; i++)
            {
                temp = age[1];
                age[1] = age[3];
                age[3] = age[3] + age[2];
                age[2] = temp;
            }
            count = age[1] + age[2] + age[3];
            printf("%d\n", count);
        }
    }
    return 0;
}

这题是很有意思的,其实就是斐波那契数列的变形。首先用递归的方法肯定不行。那么我们换一种思路,把母牛分为三种,一种是可生育的放置在age[3]里面,一种是两岁的放在age[2]里面,还有一个就是放在age[1]。然后他们三个有什么关系呢?很明显,每一年过去,一岁牛变成两岁牛,两岁牛变成可生育牛,而可生育牛的数量也是下一年一岁牛的数量。

ID 2013

#include<stdio.h>
int main()
{
    int n;
    int i;
    int total;

    while (scanf("%d", &n) != EOF)
    {
        total = 1;
        for (i = n; i > 1; i--)
        {
            total = 2 * (total + 1);
        }
        printf("%d\n", total);
    }
    return 0;

非常简单的数学游戏。

ID 2012

#include<stdio.h>
#include<math.h>
int main()
{
    int x, y, n, k, i, j;
    while (scanf("%d%d", &x, &y) != EOF)
    {
        if (x == 0 && y == 0)
            break;
        else
        {
            for (i = x, k = 1; i <= y; i++)
            {
                n = i * i + i + 41;
                for (j = 2; j<sqrt((double)n); j++)
                {
                    if (n%j == 0)
                    {
                        k = 0;
                        break;
                    }
                }
                if (k == 0)
                {
                    printf("Sorry\n");
                    break;
                }
            }
            if (k)printf("OK\n");
        }
    }
    return 0;
}

通过这题给大家一个建议,我们研究算法有时候也要去了解它背后的数学知识。比如素数判断,为何程序里写着判定区间是[2, sqrt(n)]呢?是这样的,如果一个数不是素数,那么肯定可以被除了1与它自身的数整除,也就是说一定有两个数在区间[2,n-1]之间,可以相乘得到n。这两个数肯定有一个数小于sqrt(n)。因此,以上。

ID 2010

#include<stdio.h>
#include<math.h>
int main()
{
    int m, n;
    int i,j;
    int temp;
    int num[3];
    int count;
    count = 0;
    int a[1000];
    while (scanf("%d %d", &m, &n) != EOF)
    {
        if (m > n)
        {
            temp = m;
            m = n;
            n = temp;
        }
        num[0] = num[1] = num[2] = 0;
        for (i = m; i <= n; i++)
        {
            num[2] = i / 100;
            num[1] = (i % 100)/10;
            num[0] = (i % 100) % 10;
            if (i == (num[0] * num[0] * num[0] + num[1] * num[1] * num[1] + num[2] * num[2] * num[2]))
            {
                
                count += 1;
                a[count] = i;
            }
        }

        if (count > 0)
        {
            for (j = 1; j <= count; j++)
            {
                printf("%d", a[j]);
                if (j != count)
                {
                    printf(" ");
                }
                else
                {
                    printf("\n");
                }
            }
            
        }
        if (count == 0)
        {
            printf("no\n");
        }
        count = 0;
    }
    return 0;
}

额,这题当时我记得还是遇到点挫折的,可惜记不清了。。。

ID 2009

#include<stdio.h>
#include<math.h>

int main()
{
    double n, m;
    double sum;
    int i;
    double temp;
    while (scanf("%lf %lf", &n, &m) != EOF)
    {
        sum = 0;
        for (i = 0; i < m; i++)
        {
            temp = n;
            sum = sum + temp;
            n = sqrt(n);
        }
        printf("%.2lf\n", sum);
    }
    
    return 0;
}

这题我处理的还是比较巧妙的。用一个中间变量temp储存数列下一个元素的值。

ID 2011

#include<stdio.h>
#include<math.h>

int main()
{
    int n;
    int i;
    int j;
    double sum;
    double num;
    int a[1000];

    while (scanf("%d", &n) != EOF)
    {
        for (i = 0; i < n; i++)
        {
            scanf("%d", &a[i]);
        }
        for (i = 0; i < n; i++)
        {
            num = 1.00;
            sum = 0;
            for (j = 0; j < a[i]; j++)
            {

                if (j % 2 == 0)
                {
                    num = 1.00 / (num + j);

                }
                else
                {
                    num = -(1.00 / (num + j));

                }
                
                sum = sum + num;
                num = 1.00;
            }
            printf("%0.2lf\n", sum);
        }

        
    }
    
    return 0;
}

这一题处理的也挺巧妙,精华在于num = 1.00 / (num + j)。还有要注意的一点是,我一开始提交总说我格式错误。最后百度才知道,要printf("%0.2lf\n", sum)这么写才行,少那个0会报错。

上一篇下一篇

猜你喜欢

热点阅读