PTA - No.9 - 12道题总结

这周的编程题还是有点难度的,而且代码有的比较长不好截图分享到群相册,发文本又太没意思,就直接一起记录在一个博客里好了:(所有的程序都只需要 #include <stdio.h> 所以不每个都写了

7-1 查找整数 (10 分)

本题要求从输入的N个整数中查找给定的X。如果找到,输出X的位置(从0开始数);如果没有找到,输出“Not Found”。

输入格式:

输入在第一行中给出两个正整数N(≤20)和X,第二行给出N个整数。数字均不超过长整型,其间以空格分隔。

输出格式:

在一行中输出X的位置,或者“Not Found”。

输入样例1: 5 7 

                     3 5 7 1 9

输出样例1: 2

输入样例2: 5 7

                     3 5 8 1 9

输出样例2: Not Found

int main()
{
    int N, X, t, i;
    scanf("%d%d", &N, &X);
    for(i = 0; i < N; i++)
    {
        scanf("%d", &t);
        if(t == X)
        {
            printf("%d\n", i);
            break;
        }
    }
    if(i == N)    printf("Not Found\n");
    return 0;
}

7-2 将数组中的数逆序存放 (20 分) 

将给定的n个整数存入数组中,将数组中的这n个数逆序存放,再按顺序输出数组中的元素。

输入格式:

输入在第一行中给出一个正整数n(1≤n≤10)。第二行输入n个整数,用空格分开。

输出格式:

在一行中输出这n个整数的处理结果,相邻数字中间用一个空格分开,行末不得有多余空格。

输入样例: 4

                10 8 1 2

输出样例: 2 1 8 10

int main()
{
    int n, a[10];
    scanf("%d", &n);
    for(int i = 0; i < n; i++)      scanf("%d", &a[i]);
    for(int i = n - 1; i > 0; i--)  printf("%d ", a[i]);
    printf("%d\n", a[0]);       // 行末不得有多余空格
    return 0;
}

7-3 选择法排序 (20 分)

本题要求将给定的n个整数从大到小排序后输出。

输入格式:

输入第一行给出一个不超过10的正整数n。第二行给出n个整数,其间以空格分隔。

输出格式:

在一行中输出从大到小有序的数列,相邻数字间有一个空格,行末不得有多余空格。

输入样例:4

                  5 1 7 6

输出样例:7 6 5 1

int main()
{
    int n, a[10];
    scanf("%d", &n);
    for(int i = 0; i < n; i++)    scanf("%d", &a[i]); // 先全读进来
    for(int i = 0; i < n - 1; i++)      // 每次选一个最小的和有序列后一位交换
    {
        int minV = a[i], minIdx = i;      // 最小值,最小值位置
        for(int j = i + 1; j < n; j++)
            if(a[j] < minV)
            {
                minV = a[j];
                minIdx = j;
            }
        if(minIdx != i)
        {
            int tmp = a[i];
            a[i] = a[minIdx];
            a[minIdx] = tmp;
        }
    }
    for(int i = n - 1; i > 0; i--)
        printf("%d ", a[i]);
    printf("%d\n", a[0]);   // 行末不得有多余空格
    return 0;
}

7-4 交换最小值和最大值 (15 分)

先将输入的一系列整数中的最小值与第一个数交换,然后将最大值与最后一个数交换,最后输出交换后的序列。

注意:题目保证最大和最小值都是唯一的。

输入格式:

输入在第一行中给出一个正整数N(≤10),第二行给出N个整数,数字间以空格分隔。

输出格式:

在一行中顺序输出交换后的序列,每个整数后跟一个空格。

输入样例:5

                  8 2 5 1 4

输出样例:1 2 5 4 8

int main()
{
    int n, a[10];
    scanf("%d", &n);
    for (int i = 0; i < n; i++)		scanf("%d", &a[i]);
    int max = -1, maxi = -1, min = 2147483647, mini = -1; // INT_MAX
    for(int i = 0; i < n; i++)
        if(a[i] < min)
        {
            min = a[i];
            mini = i;
        }
    a[mini] = a[0];
    a[0] = min;
    for(int i = 0; i < n; i++)  // 必须重新计算,因为交换min之后,最大值位置可能变了
        if(a[i] > max)
        {
            max = a[i];
            maxi = i;
        }
    a[maxi] = a[n - 1];
    a[n - 1] = max;
    for(int i = 0; i < n; i++)
        printf("%d ", a[i]);
    return 0;
}

7-5 简化的插入排序 (15 分)

本题要求编写程序,将一个给定的整数插到原本有序的整数序列中,使结果序列仍然有序。

输入格式:

输入在第一行先给出非负整数N(<10);第二行给出N个从小到大排好顺序的整数;第三行给出一个整数X。

输出格式:

在一行内输出将X插入后仍然从小到大有序的整数序列,每个数字后面有一个空格。

输入样例:

5

1 2 4 5 7

3

输出样例:

1 2 3 4 5 7

int main()
{
    int N, a[10], X;
    scanf("%d", &N);
    for(int i = 0; i < N; i++)
        scanf("%d", &a[i]);
    scanf("%d", &X);
    int i;
    for(i = 0; i < N; i++)
        if(a[i] > X)
        {
            for(int j = N; j > i; j--)
                a[j] = a[j - 1];
            a[i] = X;
            break;
        }
    if(i == N)                  // 都比X小
        a[N] = X;
    for(int i = 0; i <= N; i++)
        printf("%d ", a[i]);    // 每个数字后面有一个空格
    return 0;
}

7-6 求一批整数中出现最多的个位数字 (20 分)

给定一批整数,分析每个整数的每一位数字,求出现次数最多的个位数字。例如给定3个整数1234、2345、3456,其中出现最多次数的数字是3和4,均出现了3次。

输入格式:

输入在第1行中给出正整数N(≤1000),在第二行中给出N个不超过整型范围的非负整数,数字间以空格分隔。

输出格式:

在一行中按格式“M: n1 n2 ...”输出,其中M是最大次数,n1、n2、……为出现次数最多的个位数字,按从小到大的顺序排列。数字间以空格分隔,但末尾不得有多余空格。

输入样例:

3

1234 2345 3456

输出样例:

3: 3 4

int main()
{
    int N, a[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, maxTime = 0;
    scanf("%d", &N);
    for (int i = 0; i < N; i++)
    {
        int t;
        scanf("%d", &t);      // 非负整数
        do
        {
            ++a[t % 10];
            t /= 10;
        } while (t != 0)      // do while处理数字为0的情况
    }
    for (int i = 0; i < 10; i++)
        if (a[i] > maxTime)
            maxTime = a[i];
    printf("%d:", maxTime);
    for (int i = 0; i < 10; i++)
        if (a[i] == maxTime)
            printf(" %d", i);
    return 0;
}

7-7 输出数组元素 (15 分)

本题要求编写程序,对顺序读入的n个整数,顺次计算后项减前项之差,并按每行三个元素的格式输出结果。

输入格式:

输入的第一行给出正整数n(1<n≤10)。随后一行给出n个整数,其间以空格分隔。

输出格式:

顺次计算后项减前项之差,并按每行三个元素的格式输出结果。数字间空一格,行末不得有多余空格。

输入样例:

10
5 1 7 14 6 36 4 28 50 100

输出样例:

-4 6 7
-8 30 -32
24 22 50
int main()
{
    int N, a[10];
    scanf("%d", &N);
    for (int i = 0; i < N; i++)  scanf("%d", &a[i]);  // n个整数
    for(int i = 0; i < N - 1; i++)
    {
        printf("%d", a[i + 1] - a[i]);
        if((i + 1) % 3 == 0 || i == N - 2)  printf("\n");
        else                                printf(" ");
    }
    return 0;
}

7-8 找出不是两个数组共有的元素 (20 分)

给定两个整型数组,本题要求找出不是两者共有的元素。

输入格式:

输入分别在两行中给出两个整型数组,每行先给出正整数N(≤20),随后是N个整数,其间以空格分隔。

输出格式:

在一行中按照数字给出的顺序输出不是两数组共有的元素,数字间以空格分隔,但行末不得有多余的空格。题目保证至少存在一个这样的数字。同一数字不重复输出。

输入样例:

10 3 -5 2 8 0 3 5 -15 9 100
11 6 4 8 2 6 -5 9 0 100 8 1

输出样例:

3 5 -15 6 4 1

解:

    这道题网上很多答案用了三个数组,我用了一个数组,flag数组是用来代替数组删除操作的,不怎么影响时间复杂度。

int main()
{
    int an, ancnt, bn, tmp, cnt = 0, first = 1;
    // C static数组默认全初始化为0, flag[i]为0表示res[i]这位数不输出
    static int res[40], flag[40];   // 用flag数组代替删除操作
    scanf("%d", &an);
    ancnt = an;
    for (int i = 0; i < an; i++)    // 读第一个数组, 跳过重复的
    {
        scanf("%d", &tmp);
        int j = 0;
        for (j = 0; j < cnt; j++)
            if (flag[j] == 1 && res[j] == tmp)
                break;
        if (j == cnt)
        {
            res[cnt] = tmp;
            flag[cnt] = 1;
            ++cnt;
        }
        else
            --ancnt;                // 记录第一个数组存入res多少个数!!
    }
    scanf("%d", &bn);
    for (int i = 0; i < bn; i++)    // 读第二个数组, res中出现过的话,对应位flag归0,继续下一个数
    {
        scanf("%d", &tmp);
        int j = 0;
        for (j = 0; j < cnt; j++)
            if (res[j] == tmp)    // 这里不能判断flag!!!!!!因为只要出现过就一定不需要了
                break;
        if (j == cnt)             // res中没出现过
        {
            res[cnt] = tmp;
            flag[cnt] = 1;
            ++cnt;
        }
        else if (j < ancnt)       // 在第一个数组中出现过
            flag[j] = 0;
        // 在第二个数组中重复了就直接跳过
    }
    for (int i = 0; i < 40; i++)
        if(flag[i] == 1 && first == 1)
        {
            printf("%d", res[i]);
            first = 0;
        }
        else if(flag[i] == 1)
            printf(" %d", res[i]);
    return 0;
}

7-9 求整数序列中出现次数最多的数 (15 分)

本题要求统计一个整型序列中出现次数最多的整数及其出现次数。

输入格式:

输入在一行中给出序列中整数个数N(0 < N ≤ 1000),以及N个整数。数字间以空格分隔。

输出格式:

在一行中输出出现次数最多的整数及其出现次数,数字间以空格分隔。题目保证这样的数字是唯一的。

输入样例:

10 3 2 -1 5 3 4 3 0 3 2

输出样例:

3 4

int main()
{
    int N = 0, num = 0, a[1000], maxTime = -1, maxIdx = -1;
    static int cnt[1000];
    scanf("%d", &N);
    for (int i = 0; i < N; i++)
    {
        int tmp, j;
        scanf("%d", &tmp);
        for (j = 0; j < num; j++)
            if (a[j] == tmp)
            {
                ++cnt[j];
                break;
            }
        if (j == num)
        {
            a[num] = tmp;
            cnt[num] = 1;
            ++num;
        }
        if (cnt[j] > maxTime)
        {
            maxTime = cnt[j];
            maxIdx = j;
        }
    }
    printf("%d %d\n", a[maxIdx], maxTime);
    return 0;
}

7-10 求最大值及其下标 (20 分)

找出给定的n个数中的最大值及其对应的最小下标(下标从0开始)。

输入格式:

输入在第一行中给出一个正整数n(1<n≤10)。第二行输入n个整数,用空格分开。

输出格式:

在一行中输出最大值及最大值的最小下标,中间用一个空格分开。

输入样例:

6

2 8 10 1 9 10

输出样例:

10 2 

int main()
{
    int n, tmp, maxV = -2147483648, maxIdx = -1;
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        scanf("%d", &tmp);
        if(tmp > maxV)
        {
            maxV = tmp;
            maxIdx = i;
        }
    }
    printf("%d %d\n", maxV, maxIdx);
    return 0;
}

7-11 特殊a串数列求和 (20 分)

给定两个均不超过9的正整数a和n,要求编写程序求a+aa+aaa++⋯+aa⋯a(n个a)之和。

输入格式:

输入在一行中给出不超过9的正整数a和n。

输出格式:

在一行中按照“s = 对应的和”的格式输出。

输入样例:

2 3

输出样例:

s = 246

int main()
{
    int a, n, sum = 0;
    scanf("%d%d", &a, &n);
    // 2 + 22 + 222 就是一个200,两个20,三个2
    for(int i = 1; i <= n; i++)
        sum += a * (int)pow(10, n - i) * i;
    printf("s = %d\n", sum);
    return 0;
}

7-12 兔子繁衍问题 (15 分)

一对兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假如兔子都不死,请问第1个月出生的一对兔子,至少需要繁衍到第几个月时兔子总数才可以达到N对?

输入格式:

输入在一行中给出一个不超过10000的正整数N。

输出格式:

在一行中输出兔子总数达到N最少需要的月数。

输入样例:

30

输出样例:

9

解:

     这道题其实手算几个之后就找到规律了,其实就是斐波那契数列:

     第几个月:1、2、3、4、5

     几对兔子:1、1、2、3、5

int main()
{
    int n, f1 = 1, f2 = 1, months = 0;
    scanf("%d", &n);
    for (months = 1;; months++)
    {
        if(f1 >= n)
        {
            printf("%d\n", months);
            return 0;
        }
        f2 = f1 + f2;
        f1 = f2 - f1;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Bob__yuan/article/details/84350852