相信你是最棒哒!!!
一、重礼仪的贪心小Z
问题描述
小Z最近在研究一种倒酒礼仪“步步高升”,以满足自己的好奇心需要。
现在有 𝑛n 个酒杯,编号分别为 1 到 𝑛n,在小郑自研的倒酒礼仪“步步高升”中,酒杯中的酒是递增的,也就是第 𝑖+1i+1 杯酒必须要比第 𝑖i 杯酒多,且每个酒杯不能为空。
但小Z没有多余的酒,但可以将某个杯子中的酒导入其他杯子中,并且可以倒无数次。当然,小Z也可以喝掉任意酒杯中任意单位体积的酒,以满足倒酒礼仪“步步高升”的需要。
其中,每个杯子的容量可以视为无限大的,且转倒、喝掉的酒单位体积数都为整数。
小Z想要在遵循倒酒礼仪的前提下喝到最多的酒,你可以求出小Z最多能喝到多少单位体积的酒吗?
输入格式
第一行 1 个整数 𝑛n,代表酒杯数量。
第二行 𝑛n 个整数 𝑎1,𝑎2,𝑎3...,𝑎𝑛a1,a2,a3...,an,代表酒杯中已经装了的单位体积值。
输出格式
输出一行,输出最多能喝到多少单位体积的酒。如果无法做到“步步高升”的要求,输出 -1,数据保证答案唯一。
样例输入 1
2
3 2
样例输出 1
2
样例输入 2
3
1 1 1
样例输出 2
-1
对于所有测评数据 ,1≤n≤100, 1≤ai≤10
题目代码
解析版:
#include<stdio.h>
int main()
{
int n, a[1000], i, min, sum=0; // min为计算出的最小酒量总和,sum用于累加酒量
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
min = 0.5 * n * (1+n); // 计算满足“步步高升”条件的最小酒量总和,即等差数列的和,首项为1,末项为n
for (i = 0; i < n; i++) // 循环累加所有酒杯中的酒量
sum += a[i];
if (sum < min) // 如果酒量的总和小于最小酒量总和,无法满足“步步高升”的要求
printf("-1"); // 输出-1
else // 否则
printf("%d", sum - min); // 输出可以喝到的最多酒量,即总酒量减去最小酒量总和
return 0;
简洁版:
#include<stdio.h>
int main()
{
int n, a[1000], i, min, sum=0;
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
min = 0.5 * n * (1+n);
for (i = 0; i < n; i++)
sum += a[i];
if (sum < min)
printf("-1");
else printf("%d", sum - min);
return 0;
}
二、跳跳棋
问题描述
- 游戏棋盘是一个7x7的矩阵。
- 棋子(1)只能跳过相邻的棋子到空位(0)上,并且吃掉被跳过的棋子。
- 判断游戏是否结束,即无法再进行合法的跳棋操作。
输入格式
- 输入数据占7行,每行代表棋盘的一行。
- 每个位置上的数字为1或0,1表示有棋子,0表示没有。
输出格式
- 如果游戏无法进行下去,输出"yes"。
- 否则,输出"no"。
样例输入
000
001
0000001
0000000
0000101
000
000
样例输出
yes
题目代码:
解析版:
#include<stdio.h>
// 定义一个10x10的字符数组来存储棋盘状态,'1' 表示有棋子,'0' 表示没有棋子(定义成7×7的容易越界)
char a[10][10];
int main() {
int f = 0; // 用于标记是否存在可跳的棋子,初始为0,表示没有(flag)
//1. 读取第1行和第2行数据
for (int i = 1; i <= 2; i++) {
for (int j = 3; j <= 5; j++) {
scanf("%c", &a[i][j]);
}
getchar(); // 吸收换行符
}
// 读取棋盘的第4行到第6行数据,实际是第3行到第5行数据
for (int i = 3; i <= 5; i++) {
for (int j = 1; j <= 7; j++) {
scanf("%c", &a[i][j]);
}
getchar(); // 同样读取并丢弃换行符
}
// 读取棋盘的第7行和第8行数据,实际是第6行和第7行数据
for (int i = 6; i <= 7; i++) {
for (int j = 3; j <= 5; j++) {
scanf("%c", &a[i][j]);
}
getchar(); // 读取并丢弃换行符
}
// 2. 遍历棋盘,检查是否有可跳的棋子
for (int i = 1; i <= 7; i++) {
for (int j = 1; j <= 7; j++) {
if (a[i][j] == '1') { // 如果当前位置有棋子
// 检查上下左右四个方向是否有可跳的棋子
if (a[i - 1][j] == '1' && a[i - 2][j] == '0') {
f = 1; // 如果可以跳,标记为1(如果有时间限制可以在每一个后面加上break;)
}
if (a[i + 1][j] == '1' && a[i + 2][j] == '0') {
f = 1;
}
if (a[i][j - 1] == '1' && a[i][j - 2] == '0') {
f = 1;
}
if (a[i][j + 1] == '1' && a[i][j + 2] == '0') {
f = 1;
}
}
}
}
// 根据标记判断游戏是否结束
if (f == 0) {
printf("yes"); // 如果没有可跳的棋子,输出"yes"
} else {
printf("no"); // 否则输出"no"
}
return 0; // 程序结束
}
简洁版:
#include<stdio.h>
char a[10][10];
int main()
{
int f = 0;
for (int i = 1; i <= 2; i++)
{
for (int j = 3; j <= 5; j++)
{
scanf("%c", &a[i][j]);
}
getchar();
}
for (int i = 3; i <= 5; i++)
{
for (int j = 1; j <= 7; j++)
{
scanf("%c", &a[i][j]);
}
getchar();
}
for (int i = 6; i <= 7; i++)
{
for (int j = 3; j <= 5; j++)
{
scanf("%c", &a[i][j]);
}
getchar();
}
for (int i = 1; i <= 7; i++)
{
for (int j = 1; j <= 7; j++)
{
if (a[i][j] == '1')
{
if (a[i - 1][j] == '1' && a[i - 2][j] == '0')
{
f = 1;
}
if (a[i + 1][j] == '1' && a[i + 2][j] == '0')
{
f = 1;
}
if (a[i][j - 1] == '1' && a[i][j - 2] == '0')
{
f = 1;
}
if (a[i][j + 1] == '1' && a[i][j + 2] == '0')
{
f = 1;
}
}
}
}
if (f == 0)
{
printf("yes");
}
else
{
printf("no");
}
return 0;
}
二维数组中,外层循环表示行,内层循环表示列
这段代码首先定义了一个10x10的字符数组来存储棋盘状态,然后通过循环读取用户输入的棋盘数据。接着,它遍历棋盘,检查每个棋子是否有可跳的路径。如果找到可跳的棋子,就将标记f
设置为1。最后,根据f
的值判断游戏是否结束,并输出相应的结果。
总结
两个蓝桥题目,重礼仪的小Z 和 跳跳棋