> 我的学号:1706010513 ## 题目1 海滩上有一堆金币,其中每个金币的重量相等,一共有五个海盗来分,第一个海盗把这堆金币**平均分为五份,发现多了一个金币,他把多的这个金币扔到海里,拿走其中一份**。接着第二个海盗把剩下的金币又平均分为五份,又多了一个金币,他同样把多的这个金币扔到海里,拿走其中的一份,第三、第四、第五个海盗都这么做,请问海滩上在一开始**最少必须有多少个金币**。 请尝试解决该问题并画出该问题的程序流程图。 我们可以看到假设初始的金币为 $x_0$,那么第一个海盗拿了之后的金币是剩下 $x_1 = x_0 - {\lfloor {x_0 \over 5} \rfloor} - 1$,并且这里 $x_i \% 5 == 1$ 且连续满足 5 次。 所以我们可以暴力枚举初始的金币,看看哪个值符合最后的要求。 但是这样做比较慢。 比较好一点的方法是枚举最后一个海盗得到的金币,逆推这个过程,并判断过程中金币数量是否一直满足题目的要求。 代码: ```cpp #include int calc(int n) { int last_coins=n*5+1; for(int i = 0;i < 4;i++){ if(last_coins%4==0){ last_coins=last_coins/4*5+1; } else return -1; } return last_coins; } int main() { int defaultc=0; //puts("input the coins last pirate get(default:0):"); while(~calc(defaultc)==0) defaultc++; printf("Initially,there are at least %d coins. last one get %d",calc(defaultc),defaultc); } ``` --- ## 题目二 求两个自然数,其和为 667,最小公倍数与最大公约数之比为 120:1。 即求解两数 x, y,满足: $$ \begin{cases} x+y=667 \\[2ex] \frac {x*y}{gcd(x,y)^2}=120 \end{cases} $$ 这个题目我们可以用辗转相除法写一个 gcd 函数~~(或者直接使用 `#include ` 中的 `__gcd()`)~~。 而两个数的最小公倍数其实就是他们的积再除以他们的最大公约数。 最简单就是**暴力枚举 i, j,判断 i+j 是否等于 667,再计算它们最小公倍数与最小公约数的比值是否为 120**。 但是简化之后就是**设一个数为 i,则另一个数就是 667-i**。 这样我们再去枚举就会简单多了。 代码: ```cpp #include int gcd(int a,int b) { if(a int main() { puts("Please input two integers x and y:"); int x,y; scanf("%d%d",&x,&y); printf("Answer is %d\n",x>y?x-y:x+y); return 0; } ``` ## 题目四 框图大意: ``` Program: i=1,j=m; while(i Loading... > 我的学号:1706010513 ## 题目1 海滩上有一堆金币,其中每个金币的重量相等,一共有五个海盗来分,第一个海盗把这堆金币**平均分为五份,发现多了一个金币,他把多的这个金币扔到海里,拿走其中一份**。接着第二个海盗把剩下的金币又平均分为五份,又多了一个金币,他同样把多的这个金币扔到海里,拿走其中的一份,第三、第四、第五个海盗都这么做,请问海滩上在一开始**最少必须有多少个金币**。 请尝试解决该问题并画出该问题的程序流程图。 我们可以看到假设初始的金币为 $x_0$,那么第一个海盗拿了之后的金币是剩下 $x_1 = x_0 - {\lfloor {x_0 \over 5} \rfloor} - 1$,并且这里 $x_i \% 5 == 1$ 且连续满足 5 次。 所以我们可以暴力枚举初始的金币,看看哪个值符合最后的要求。 但是这样做比较慢。 比较好一点的方法是枚举最后一个海盗得到的金币,逆推这个过程,并判断过程中金币数量是否一直满足题目的要求。 代码: ```cpp #include <cstdio> int calc(int n) { int last_coins=n*5+1; for(int i = 0;i < 4;i++){ if(last_coins%4==0){ last_coins=last_coins/4*5+1; } else return -1; } return last_coins; } int main() { int defaultc=0; //puts("input the coins last pirate get(default:0):"); while(~calc(defaultc)==0) defaultc++; printf("Initially,there are at least %d coins. last one get %d",calc(defaultc),defaultc); } ``` --- ## 题目二 求两个自然数,其和为 667,最小公倍数与最大公约数之比为 120:1。 即求解两数 x, y,满足: $$ \begin{cases} x+y=667 \\[2ex] \frac {x*y}{gcd(x,y)^2}=120 \end{cases} $$ 这个题目我们可以用辗转相除法写一个 gcd 函数~~(或者直接使用 `#include <algorithm>` 中的 `__gcd()`)~~。 而两个数的最小公倍数其实就是他们的积再除以他们的最大公约数。 最简单就是**暴力枚举 i, j,判断 i+j 是否等于 667,再计算它们最小公倍数与最小公约数的比值是否为 120**。 但是简化之后就是**设一个数为 i,则另一个数就是 667-i**。 这样我们再去枚举就会简单多了。 代码: ```cpp #include <cstdio> int gcd(int a,int b) { if(a<b) return gcd(b,a); return a%b==0?a:gcd(b,a%b); } int lcm(int a,int b) { return a*b/gcd(a,b); } int main() { for(int i = 1;i < 334;i++){ if(lcm(i,667-i)/gcd(i,667-i)==120) printf("%d %d is a pair of answer\n",i,667-i); } return 0; } ``` --- ## 题目三 非常简单,上图上代码。 框图 1: ![t1][1] 代码 1: ```cpp long long fac(long long n) { if(n==0||n==1) return 1; else return n*fac(n-1); } ``` 框图 2: ![t2][2] 代码 2: ```cpp #include <cstdio> int main() { puts("Please input two integers x and y:"); int x,y; scanf("%d%d",&x,&y); printf("Answer is %d\n",x>y?x-y:x+y); return 0; } ``` ## 题目四 框图大意: ``` Program: i=1,j=m; while(i<n): j*=m; i++; z=j; 输出z; End. ``` [1]: https://hodam.top/myfile/image/homework/3_1.png [2]: https://hodam.top/myfile/image/homework/3_2.png Last modification:April 9, 2019 © Allow specification reprint Support Appreciate the author Like 如果觉得我的文章对你有用,请随意赞赏