ch3题解

A_数组逆序重放

代码:
#include <bits/stdc++.h>
using namespace std;
// #include <stdio.h>

// 题意:数组逆置
int main()
{
    int a[110];// 1 < n < 100
    int n; scanf("%d", &n);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
    
    /* 方法一:直接输出就可以 */
    // for (int i = n; i >= 1; i -- ) printf("%d ", a[i]);

    /* 方法二:操作数组 一重循环 */ 
    int l = 1, r = n;// 开两个变量,指向数组的两头
    while (l < r)
    {
        // 交换两头

        // c语言 交换
        int t = a[l];
        a[l] = a[r];
        a[r] = t;

        // c++ 库函数交换
        // swap(a[l], a[r]);

        l ++;
        r --;
    }
    for (int i = 1; i <= n; i ++ ) printf("%d ", a[i]);
    return 0;
}

双重循环交换反转数组的方法

代码:
// 选自同学的提交:https://vjudge.net/solution/65504587
#include<stdio.h>
#include<math.h>
int main()
{
	int a,b,c,d,e,f,i,n,t,sum=0,max=0;
	scanf("%d",&n); 
	int z[n];
	for(i=0;i<n;i++)
	{
		scanf("%d",&z[i]);
	}
	for(i=0;i<n;i++)
	{
		for(a=i;a<n;a++)
		{
			t=z[i];
			z[i]=z[a];
			z[a]=t;
		}
	}
	for(i=0;i<n;i++)
	{
		printf("%d ",z[i]);
	}
	return 0;
}

B_查找特定的值

代码:
#include <bits/stdc++.h>
using namespace std;
// #include <stdio.h>

// 题意:在数组中查找x,没有返回-1
int main()
{
    int a[10010];// 1 <= n <= 10000
    int n; scanf("%d", &n);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
    int x; scanf("%d", &x);

    int idx = -1;// index
    for (int i = 1; i <= n; i ++ ) 
    {
        if (a[i] == x)
        {
            idx = i;
            break;
        }
    }
    printf("%d", idx);
    return 0;
}

C_与指定数字相同的数的个数

代码:
#include <bits/stdc++.h>
using namespace std;
// #include <stdio.h>

// 题意:寻找m在数组中出现的次数
int main()
{
    int a[110];// n <= 100
    int n; scanf("%d", &n);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
    int m; scanf("%d", &m);

    // 思路:遍历一遍统计一下m的个数
    int cnt = 0; // count
    for (int i = 1; i <= n; i ++ )
    {
        if (a[i] == m) cnt ++;
    }
    printf("%d", cnt);

    return 0;
}

D_整数去重

解法一:

代码:
#include <bits/stdc++.h>
using namespace std;
// #include <stdio.h>

// 题意:数组去重,按原来顺序输出
int main()
{
    int a[20010];// 1 <= n <= 20000
    int n; scanf("%d", &n);
    for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);

    int vis[110];// 开一个visit数组,标记这个数是否出现过
    // 题目中说了"第二行包含n个整数,整数之间以一个空格分开。每个整数大于等于10、小于等于100。"
    for (int i = 10; i <= 100; i ++ ) vis[i] = 0;
    // 全赋值为0,表示未访问

    for (int i = 1; i <= n; i ++ )
    {
        if (vis[a[i]] == 1) continue;
        vis[a[i]] = 1;
        printf("%d ", a[i]);
    }

    return 0;
}

解法二:

代码:
// 选自同学提交的代码:https://vjudge.net/solution/65505911
#include<stdio.h>
int main()
{
	int i,str[20000],t,n,j,ZZS1=0;
	scanf("%d",&t);
	for(i=0;i<t;i++)
	{
		scanf("%d",&n);
		str[i]=n;
	}
	for(i=0;i<t;i++)
	{
		for(j=0;j<i;j++)
		{
			if(str[j]==str[i])
			{
				ZZS1++;
				break;
			}
		}
		if(ZZS1==1)
		{
			ZZS1=0;
			continue;
		}
		printf("%d ",str[i]);
	}
}

E_矩阵交换行

e题有个比较坑的点,就是他问的m,n是第几行从1开始的,如果你的数组索引从0开始存的,那就要m--,n--。

代码:
#include <bits/stdc++.h>
using namespace std;
// #include <stdio.h>

// 题意:二维矩阵两个行互相交换
int main()
{
    int a[10][10];
    for (int i = 1; i <= 5; i ++ )
    {
        for (int j = 1; j <= 5; j ++ )
        {
            scanf("%d", &a[i][j]);
        }
    }

    int n, m;
    scanf("%d%d", &n, &m);
    // 交换 n和 m 行
    for (int j = 1; j <= 5; j ++ )
    {
        // 借助变量t交换
        int t = a[n][j];
        a[n][j] = a[m][j];
        a[m][j] = t;

        // 使用c++ swap库函数交换
        // swap(a[n][j], a[m][j]);
    }

    for (int i = 1; i <= 5; i ++ )
    {
        for (int j = 1; j <= 5; j ++ )
        {
            printf("%d ", a[i][j]);
        }
        printf("\n");
    }

    return 0;
}

F_计算鞍点

题目保证:每行有唯一最大值、每列有唯一最小值

所以最多有一个鞍点(凭感觉可以猜出来,或者去问一下ai,反证法证明"在一个 \(n\)\(n\) 列的矩阵中,每行只有一个最大值,每列只有一个最小值。证明鞍点数量最多为 \(1\)。")

解法一:

代码:
#include <bits/stdc++.h>
using namespace std;
// #include <stdio.h>

// 题意:统计行和列的最值信息,找鞍点
int main()
{
    int a[10][10];
    for (int i = 1; i <= 5; i ++ )
    {
        for (int j = 1; j <= 5; j ++ )
        {
            scanf("%d", &a[i][j]);
        }
    }

    // 统计每一行的最大值,每一列的最小值
    int row[10], col[10]; // row表示行,col表示列

    // 先初始化一下数组
    for (int i = 1; i <= 5; i ++ )
    {
        row[i] = -1;
        col[i] = 1e9; // 科学计数法表示,10的9次方
    }
    // 相当于第1,2...5行最大值当前都是-1
    // 第1,2...5列最小值都是1000000000
    
    for (int i = 1; i <= 5; i ++ )
    {
        for (int j = 1; j <= 5; j ++ )
        {
            // 遍历每个数a[i][j], 更新他对应行列的最值

            // c语言
            if (a[i][j] > row[i]) row[i] = a[i][j];
            if (a[i][j] < col[j]) col[j] = a[i][j];

            // c++ max,min库函数
            // row[i] = max(row[i], a[i][j]);
            // col[j] = min(col[j], a[i][j]);
        }
    }

    // 打印一下col和row数组(调试用)
    // for (int i = 1; i <= 5; i ++ )
    // {
    //     printf("第%d行的最大值为%d\n", i, row[i]);
    // }
    // for (int i = 1; i <= 5; i ++ )
    // {
    //     printf("第%d列的最大值为%d\n", i, col[i]);
    // }

    // 查找答案
    int i, j, flag = 0;//flag标记一下找没找到
    for (i = 1; i <= 5; i ++ )
    {
        for (j = 1; j <= 5; j ++ )
        {
            if (row[i] == col[j])
            {
                printf("%d %d %d", i, j, row[i]);
                flag = 1;
                break;
            }
        }
        if (flag == 1) break;
    }
    if (flag == 0) cout << "not found";
    return 0;
}

解法二:

代码:
//选自同学的提交:https://vjudge.net/solution/65507489
#include<stdio.h>
#include<math.h>
int main()
{
	long long int a,b,c,d,e,f,i,n=0,t=0,sum=0,max=0,min=0;
	long long int z[5][5];
	for(a=0;a<5;a++)
	{
		for(b=0;b<5;b++)
		{
			scanf("%lld",&z[a][b]);
		}
	}
	for(a=0;a<5;a++)
	{
		for(b=0;b<5;b++)
		{
			if(z[a][b]>max)
			{
				max=z[a][b];
				e=b;
			}
		}
		min=z[0][e];
		for(f=0;f<5;f++)
		{
			if(z[f][e]<min)
			{
				min=z[f][e];
			}
		}
		if(max==min)
		{
			printf("%d %d %d",a+1,e+1,max);
			n=1;
		}
		max=0;
	}
	if(n==0)
	{
		printf("not found");
	}
	return 0;
}

G_猜数字

解法一:枚举所有可能方案

首先根据 它的七进制与九进制表示都是三位数, 可以推出一个大致的范围。

比如 九进制三位数最小为 \((100)_9 = 81\),七进制三位数最大为 \((777)_7 = 497\)

就直接遍历 \([81, 497]\),计算出对应的七进制数和九进制数看是不是表示顺序正好相反。

或者直接选一个大范围比如 \([1, 1000]\)

解法一代码:
#include<bits/stdc++.h>
using namespace std;

int main()
{
    // 七进制 777 -> 497, 100 -> 49
    // 九进制 100 -> 81 
    for (int i = 81; i <= 497; i ++ )
    {
        int seven[3] = {i % 7, i / 7 % 7, i / 49 % 7};// 我这里是倒着存的,所以后面倒着输出
        int nine[3] = {i % 9, i / 9 % 9, i / 81 % 9};
        if (seven[0] == nine[2] and seven[1] == nine[1] and seven[2] == nine[0])
        {
            printf("%d\n", i);
            for (int i = 2; i >= 0; i -- ) 
            {
                printf("%d", seven[i]);
            }
            printf("\n");
            for (int i = 2; i >= 0; i -- ) 
            {
                printf("%d", nine[i]);
            }
            printf("\n");
            break;
        }
    }
    return 0;
}

解法二:数学解法

设十进制数 \(n\) 的七进制表示为 \(abc\),则 \(n\) 的九进制表示为 \(cba\)

\(0 \leq a, b, c \leq 9\)

\(a \times 7^2 + b \times 7 + c = c \times 9^2 + b \times 9 + a\)

\(48a - 2b - 80c = 0\)

a是abc的第一位数字,c是cba的第一位数字,都不能为0
abc是七进制数字,每一位的数码只能是0~6中的一个。
暴力搜索a,b,c的所有可能取值,即可搜索到满足条件的a,b,c

然后枚举 \(a, b, c\) 找满足条件的 \(a\)\(b\)\(c\)

最后输出

十进制:\(a \times 7^2 + b \times 7 + c\)

七进制:\(abc\)

九进制:\(cba\)

解法二代码:
#include<bits/stdc++.h>
using namespace std;

int main()
{
    int a, b, c;
    for(a = 1; a <= 6; a ++)
    {
        for(b = 0; b <= 6; b ++)
        {
            for(c = 1; c <= 6; c ++)
            {
                if(48 * a - 2 * b - 80 * c == 0)
                {
                    printf("%d\n%d%d%d\n%d%d%d", a * 49 + b * 7 + c, a, b, c, c, b, a);
                    return 0;
                }
            }
        }     
    }
        
    return 0;
}
posted @ 2025-11-11 21:02  __whx  阅读(21)  评论(0)    收藏  举报