R7-5 大家分糖果
小朋友围成环形分糖果,这里我们可以考虑用数组解决。
- 本题的解题:
- 先读取每个小朋友的糖果数。
- 读取游戏轮数,模拟游戏的进行。
- 两层循环,外层是游戏的轮数,内层是每轮游戏对小朋友的遍历。 当前轮轮到第i位小朋友。
- 第i位小朋友吃掉分成三份后剩余的糖果数。
- 第i位小朋友将分成三份的糖果数取一份自留,即将拥有的糖果数修改为平分三份后的一份的糖果数。邻座的两位小朋友需要将自己拥有的糖果数加上被第i位小朋友分到的糖果数。
代码处理解释
- 下标的循环:数组cnt[]存储每个小朋友初始的糖果数,下标设为0~n-1(0~n-1比设坐标为1~n好处理),因为1号和n号小朋友是坐在一起的,也就是0号下标往后一位就是n-1位,往前一位是1位,这是本题解决环形座位的一个重要点。
(i - 1 + n) % n
就是第i位后退一位的下标,为了防止i-1小于0,所以让i-1又+n。这块怎么理解呢?- 如果i-1还是大于等于0,
(i - 1 + n) % n
等于(i - 1 ) % n + n % n
即i-1
。 - 如果i-1小于0,也就是-1,
(i - 1 + n) % n
等于(i - 1 + 1 + n - 1) % n
等于(n - 1) % n
即n-1
。
- 如果i-1还是大于等于0,
(i + 1) % n
同理。
#include<stdio.h>
int main() {
int n;//小朋友的人数
int cnt[100];
//存放每个小朋友糖果数量,存储的下标是0~n-1,输出的下标是1~n
//从0开始实现循环方便
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &cnt[i]);
int m;//游戏轮数
scanf("%d", &m);
while (m--) {
for (int i = 0; i < n; i++) {
cnt[i] -= (cnt[i] % 3);//小朋友吃掉分成三份后剩下的
int ecnt = cnt[i] / 3; //每一份糖果的数量
cnt[i] = ecnt;//自留
cnt[(i - 1 + n) % n] += ecnt;//分糖果
cnt[(i + 1) % n] += ecnt;
}
}
//查找拥有的最多糖果数
int maxCnt = cnt[0];
for (int i = 0; i < n; i++) {
if (cnt[i] > maxCnt) maxCnt = cnt[i];
}
//输出结果
for (int i = 0; i < n; i++) {
printf("%d ", cnt[i]);
}
printf("\n");
for (int i = 0; i < n; i++) {
if (cnt[i] == maxCnt)
printf("%d ", i + 1);//存储的下标是0~n-1,输出的下标是1~n,所以+1
}
return 0;
}
R7-6 装箱问题
本题的解题思路很简单:就是对于每一件物品,从头到尾和箱子剩余容量比对,如果箱子剩余容量大于等于当前物品大小,物品即放入。放入物品后需要更新被放入的箱子的剩余容量。
#include<stdio.h>
#include<string.h>
int cap[1001];
int main() {
int N;
scanf("%d", &N);
//初始化箱子容量
for(int j = 1; j <= N; j++)
cap[j] = 100;
for (int i = 0; i < N; i++) {
int x;
scanf("%d", &x);//第i件商品大小
for (int j = 1; j <= N; j++) {
if (x <= cap[j]) {//如果物品大小小于等于该商品剩余容量即可放置
printf("%d %d\n", x, j);
cap[j] -= x;//更新该箱子剩余容量
break;//退出内层循环
}
}
}
int cnt = 0;
//计算共用箱子数
for (int j = 1; j <= N; j++) {
if (cap[j] == 100) break;
//只要出现箱子容量为100,就说明当前即以后的箱子没被使用
cnt++;
}
printf("%d", cnt);
return 0;
}