软件工程网络工程第二次训练(AC代码和详细解释)(C语言描述)

来源:互联网 发布:mill9.1编程入门教程 编辑:程序博客网 时间:2024/06/05 09:11

作者:软件工程 E21514035 蒋渝涵

第一题

代码

#include <stdio.h>#include <math.h>int main(){ double n; while( scanf("%lf",&n)!=EOF )  printf("%.2lf\n",fabs(n));return 0;//不要用void main(),用int main(){ return 0;}} 

解释

abs( )主要用于对求整数的绝对值。而fabs( )主要是求精度要求更高的doublefloat 型的绝对值两者在只#include<cmath>时都可以使用。 

第二题

代码

#include<stdio.h>int main(){    int n;    while (scanf("%d", &n) != EOF)    {        int sum = 0;//注意放在while循环里面,每次都要初始为0        int temp , i;        for (i = 0; i < n; i++)        {            scanf("%d", &temp);            sum += temp;        }        printf("%d\n", sum);    }    return 0;}

第三题

#include<stdio.h>int main(){    int n;    while (scanf("%d", &n) != EOF)    {        int temp = n / 10;        if (n < 0 || n>100)temp = -1;//非法情况全部统一成-1        else if (temp < 6)temp = 0;//不及格全部统一成0        switch (temp)        {        case -1:printf("Score is error!\n"); break;//注意加上break        case 0:printf("E\n"); break;        case 6:printf("D\n"); break;        case 7:printf("C\n"); break;        case 8:printf("B\n"); break;        case 9:printf("A\n"); break;        case 10:printf("A\n"); break;//一百情况要单独考虑        }    }    return 0;}

注意-1/10答案是0;

第四题

#include<stdio.h>int main(){    int m, n;    while (scanf("%d%d",&m,&n) != EOF)    {        int i;        int x = 0;        int y = 0;        int temp;        if (m > n)//m,n大小不确定,需要先比较,这题出的有问题,根本没有说清楚,正规比赛不会出现这种情况= =我错了2发。        {            temp = m;            m = n;            n = temp;        }        for (i = m; i <= n; i++)        {            if (i % 2 == 0)                x += i*i;            else                y += i*i*i;        }        printf("%d %d\n", x, y);    }    return 0;}

第五题

这是网上的代码可以ac,因为本题数据量比较小,可以通过,如果数据量过大可能无法通过,现在介绍 另外一种方法初始化法。

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

初始化法

#include<stdio.h>int check[100];//数组放在全局位置会被初始化,现在里面全是0//有比这快多了的算法,但是本题数据量比较小,没有必要使用,其实连初始化法也是没有必要的,这是希望大家了解初始化法的思路,一次构造,多次查询int Prime(int temp){    if (temp % 2 == 0)        return 0;    int i;    for (i = 2; i <temp; i++)//不要把sqrt和strlen之类的函数写在for循环的判断条件里,这样每次循环都会计算,        if(temp%i == 0)            return 0;    return 1;}void init(){    int i;    for (i = 0; i <= 89; i++)//全部+39扩大到正数范围是为了使用下表访问    {        int temp = i - 39;        temp = temp*temp + temp + 41;        if (Prime(temp))            check[i] = 0;        else            check[i] = 1;    }}int main(){    int x, y;    init();    while (scanf("%d%d", &x, &y),x||y)//只有当x,y同时为0时x||y才为0,逗号表达式只看最后一项    {        int i;        x += 39;        y += 39;        int ans = 0;        for (i = x; i <= y; i++)            ans += check[i];        if (ans > 0)//说明区间之内存在不是素数的            printf("Sorry\n");//注意第一个字母大小其它小写        else            printf("OK\n");//两个字母都要大写    }    return 0;}

用法初始化法我发现个比较有趣的现象在-39到50之间只有四个数不满足那个方程算出来是素数
它们分别是40 41 44 49

(每个位置需要减去39)
这里写图片描述

这时候我们就可以调戏后台程序了

#include<stdio.h>int main(){    int x, y;    while (scanf("%d%d", &x, &y), x || y)    {        if (40 >= x && 40 <= y || 41 >= x && 41 <= y || 44 >= x && 41 <= y || 49 >= x && 49 <= y)            printf("Sorry\n");        else            printf("OK\n");    }    return 0;}

普通法和初始化法都要15ms调戏法只要0ms~调戏法还是很给力的。

第六题

解释

根据1/2pre-1=now,这个关系推出pre=(now+1)*2

代码

#include<stdio.h>int main(){    int n;    while (scanf("%d", &n) != EOF)    {        int sum = 1;        int i;        for (i = 1; i < n;i++)        sum= 2 * (sum + 1);        printf("%d\n", sum);    }    return 0;}

第七题

从下往上比较,最后顶端一定是所求的解,从上往下比较,所求解一定在最后一行中

代码(从下往上)

#include<stdio.h>int a[105][105];int max(int a, int b){    if (a > b)        return a;    else        return b;}int main(){    int T;    scanf("%d", &T);    while (T--)    {        int n;        scanf("%d", &n);        int i, j;        for (i = 1; i <=n; i++)        {            for (int j = 1; j <= i; j++)                scanf("%d", &a[i][j]);        }        for (i = n - 1; i >= 1; i--)//从倒数第二行开始因为下面有a[i+1]这样的语句        {            for (j = 1; j <=i;j++)            {                a[i][j] += max(a[i + 1][j], a[i + 1][j + 1]);            }        }        printf("%d\n", a[1][1]);        }    return 0;}

从上往下

#include<stdio.h>#define INF 1000000000int a[105][105];int max(int a, int b){    if (a > b)        return a;    else        return b;}int main(){    int T;    scanf("%d", &T);    while (T--)    {        int n;        scanf("%d", &n);        int i, j;        for (i = 1; i <=n; i++)        {            for (int j = 1; j <= i; j++)                scanf("%d", &a[i][j]);        }        for (i =2; i<=n; i++)        {            for (j = 1; j <=i;j++)            {                if (j == 1)//开头只能来自上一行开头                    a[i][j] += a[i - 1][j];                else if (j == i + 1)//结尾只能来自上一行结尾                    a[i][j] += a[i - 1][j - 1];                else//中间部分有两个选择                    a[i][j] += max(a[i - 1][j - 1], a[i - 1][j]);            }        }        int Max = -INF;        for (i = 1; i <= n; i++)//在最后一行中找出最大值        {            if (Max < a[n][i])                Max = a[n][i];        }        printf("%d\n", Max);        }    return 0;}

第一种31ms第二种62ms
第一种少了最后查找这部分更好。

第八题

第一次写搜索可能代码不是很精简,你们可以去看看李阳叔叔的代码

#include<stdio.h>#include<string.h>char M[105][105];int n, m;void search(int i, int j){    int a, b;    int C = 0;    if (i >= 1 && i<=n&&j>=1&&j<=m)//如果它在有效范围内    {        for (a = i - 1; a <= i + 1; a++)//并且身边的都是‘*’怎结束搜索        {            for (b = j - 1; b <= j + 1; b++)            {                if (a == i&&b == j)//过滤掉本身                    continue;                if (M[a][b] == '*')                {                    C++;                }            }        }        if (C == 8)//身边8个点都是            return;    }    else if (i < 1 || i>n || j < 1 || j < m)//搜到围栏直接结束    {        return;    }    for (a = i - 1; a <= i + 1; a++)//如果搜索到旁边的‘@’,就先把这个点变成‘*’,然后以这个点为新的起点继续搜索。    {        for (b = j - 1; b <= j + 1; b++)        {            if (a == i&&b == j)                continue;            if (M[a][b] == '@')            {                M[a][b] = '*';                search(a, b);            }        }    }    return;}int main(){    while (scanf("%d%d", &n, &m),n||m)    {        getchar();        int i, j;        memset(M, 0, sizeof(M));        for (i = 0; i <= n + 1; i++)//构造一个围栏        {            M[i][0] = '*';            M[i][m+1] = '*';        }        for (i = 0; i <= m + 1; i++)//构造一个围栏        {            M[0][i] = '*';            M[n + 1][i] = '*';        }        for (i = 1; i <=n; i++)        {            for (j = 1; j <= m; j++)            {                scanf("%c", &M[i][j]);            }getchar();//因为每次换行都有回车,所以要把回车过滤掉,其实如果学了c++用cin是很方便的,有空去看看c++哦        }        int ans = 0;        for (i = 1; i <=n; i++)        {            for (j = 1; j <=m; j++)                if (M[i][j] == '@')                {                search(i, j);//搜索                ans++;                }        }        printf("%d\n", ans);    }    return 0;}
1 0