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

浙公网安备 33010602011771号