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

作者:软件工程 E21514035 蒋渝涵

第一题

代码

#include 
#include 
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时都可以使用。 

第二题

代码

#include

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

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
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

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

int check[100];//数组放在全局位置会被初始化,现在里面全是0
//有比这快多了的算法,但是本题数据量比较小,没有必要使用,其实连初始化法也是没有必要的,这是希望大家了解初始化法的思路,一次构造,多次查询
int Prime(int temp)
{
    if (temp % 2 == 0)
        return 0;
    int i;
    for (i = 2; 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)
软件工程网络工程第二次训练(AC代码和详细解释)(C语言描述)_第1张图片

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

#include

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

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

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

#define INF 1000000000
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 =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
#include

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;
}

你可能感兴趣的:(软件工程,c语言,网络)