思路
思路:
本题需要学会枚举算法
题目:M条鱼一只小猫把这堆鱼平均分为 N 份,多了i个 (M%N==i),拿走一份(M/N),下一只猫看到了M/N*(N-1)条。
如果你看到了K条鱼,那么些鱼是上一只猫留下的N-1份鱼,所以K必须被K%(N-1)整除,此时就可以推算出上一只猫当时看到了 K/(N-1)*N+i条鱼,否则枚举的方案不可行,放弃,进入下一次枚举
如果可以这样推导到第一只猫,那么这就是答案了
想要完成本题首先,我们要使用枚举找到一个最小的正整数 m
(最后一只小猫会吃m条鱼),那么它当时应该看到了 m*n+i
条鱼,此时需要满足 m*n+i
能被 n-1
整除,这样就可以保证最后一只小猫分完鱼后,剩下的鱼是 n-1
的整数倍,逆推出之前小猫的当时看到的鱼 即 (m*n+i)/(n-1)*n
。
然后,我们要判断从倒数第二只小猫开始,每只小猫分鱼后,剩下的鱼是否还是 n-1
的整数倍,如果是,就说明这个 m
是满足要求的,否则,就要继续增加 m
的值,直到找到一个合适的 m。
最后,如果能够成功推导到第一只鱼看到的鱼的,那么此时的鱼的数量就是题目要求的答案,输出海滩上最少的鱼数(即逆推到的第一只猫看到的鱼,这就是第一只小猫分鱼前的鱼数)。
#include <bits/stdc++.h>
using namespace std;
int n,i;
int main(){
cin>>n>>i; // 输入小猫的数量 n 和每次扔掉的鱼的数量 i
for(int m=1;;m++){ // 从 1 开始,不断增加 m 的值,直到找到一个满足要求的 m
int k=n*m+i; // 计算第一只小猫分鱼前的鱼数,即 n*m+i
bool flag=true; // 定义一个布尔变量,用来表示是否找到了满足要求的 m,初始为 true
for(int j=2;j<=n;j++){ // 从第二只小猫开始,遍历每只小猫的编号 j
if(k%(n-1)!=0){ // 如果 k 不能被 n-1 整除,说明这个 m 不满足要求
flag=false; // 将 flag 设为 false
break; // 跳出循环
}
k=k/(n-1)*n+i; // 如果 k 能被 n-1 整除,就更新 k 的值,即下一只小猫分鱼前的鱼数
}
if(flag){ // 如果 flag 为 true,说明这个 m 是满足要求的
cout<<k<<"\n"; // 输出 k 的值,即海滩上最少的鱼数
return 0; // 结束程序
}
}
return 0;
}
思路