当前位置:   article > 正文

ZISUOJ C语言-函数

ZISUOJ C语言-函数

说明

博主是ZISU在校学生,刚学C/C++才2个多月,为了记录自己的学习过程和分享思路,故写一些博客。当然我的代码许多时候不是最优解,欢迎大家评论留言一起学习。如果有友友想提交这些题试试自己的思路啥的,可以私我,因为外校友友应该是登陆不进咱们的平台的。对于搜索到本博客的同校友友,切勿直接照抄,理解了再自己码字码上去。

题目列表

问题 A: 分段函数求解

思路:直接写,只不过这次把处理封装成一个自定义函数

 参考题解:

  1. #include <iostream>
  2. using namespace std;
  3. int f(int x){
  4. if(x < 1) return x;
  5. else if(x < 10) return 2*x-1;
  6. else return 3*x-11;
  7. }
  8. int main(){
  9. //问题 A: 分段函数求解
  10. int x;cin >> x;
  11. cout << f(x) << endl;
  12. return 0;
  13. }

问题 B: 最大公约数

思路:求最大公约数咱们这个阶段使用辗转相除法最优

 参考题解:

  1. #include <iostream>
  2. using namespace std;
  3. int gcd(int x,int y){ //辗转相除法
  4. int temp;
  5. if(x < y){
  6. temp = x;
  7. x = y;
  8. y = temp;
  9. }
  10. while(x%y!=0){
  11. temp = x % y;
  12. x = y;
  13. y = temp;
  14. }
  15. return y;
  16. }
  17. int main(){
  18. //问题 B: 最大公约数
  19. int x,y;cin >> x >> y;
  20. cout << gcd(x,y) << endl;
  21. return 0;
  22. }

问题 C: 最大公约数和最小公倍数

说明:最大公约数同上题,找最小公倍数可以通过最大公约数直接算出,但我这里使用了暴力寻找的方法

参考题解:

  1. #include <iostream>
  2. #include <cmath>
  3. using namespace std;
  4. int gcd(int x,int y){ //辗转相除法
  5. int temp;
  6. if(x < y){
  7. temp = x;
  8. x = y;
  9. y = temp;
  10. }
  11. while(x%y!=0){
  12. temp = x % y;
  13. x = y;
  14. y = temp;
  15. }
  16. return y;
  17. }
  18. int lcd(int x,int y){ //暴力寻找
  19. for(int i = max(x,y);i<=x*y;i++) if(i%x==0&&i%y==0) return i;
  20. }
  21. int main(){
  22. //问题 C: 最大公约数和最小公倍数
  23. int x,y;cin >> x >> y;
  24. cout << gcd(x,y) << " " << lcd(x,y) << endl;
  25. return 0;
  26. }

问题 D: Goldbach's conjecture

思路:暴力寻找即可,其中需要写一个判断是否为素数的自定义函数

参考题解:

  1. #include <iostream>
  2. using namespace std;
  3. bool is_Prime(int n){ //判断是否为素数
  4. if(n == 1) return false; //1不是素数
  5. if(n == 2) return true; //2为素数
  6. for(int i = 2;i*i<=n;i++) if(n%i==0) return false;//如果有因子,则不是素数
  7. return true; //没有因子,则为素数
  8. }
  9. int main(){
  10. //问题 D: Goldbach's conjecture
  11. for(int i = 4;i<=100;i+=2){
  12. cout << i << "=";
  13. for(int j = 2;j<i;j++){
  14. if(!is_Prime(j)) continue; //若j不为素数则继续找
  15. if(is_Prime(i-j)){ //如果j为素数且i-j也为素数,则输出
  16. cout << j << "+" << i-j << endl;
  17. break;
  18. }
  19. }
  20. }
  21. return 0;
  22. }

问题 E: 素数回文数的个数

思路:上一题已经写了判断是否为素数的自定义函数,这个题再加上写一个判断是否为回文数的函数即可。判断既是素数又是回文数则count++,最终输出count

参考题解:

  1. #include <iostream>
  2. using namespace std;
  3. bool is_Prime(int n){ //判断是否为素数
  4. if(n == 1) return false;
  5. else if(n == 2) return true;
  6. for(int i = 2;i*i<=n;i++) if(n%i==0) return false;
  7. return true;
  8. }
  9. bool is_Huiwen(int n){ //判断是否为回文数
  10. int temp = n,sum = 0; //左右颠倒数字判断是否相等
  11. while(temp != 0){
  12. sum = sum*10 + temp %10;
  13. temp /= 10;
  14. }
  15. if(sum==n) return true;
  16. else return false;
  17. }
  18. int main(){
  19. //问题 E: 素数回文数的个数
  20. int n,count = 0;cin >> n;//count计数
  21. //若找到既是素数又是回文数的,count加一
  22. for(int i = 11;i<=n;i++) if(is_Prime(i)&&is_Huiwen(i)) count++;
  23. cout << count << endl;
  24. return 0;
  25. }

 问题 F: 判决素数个数

思路:同样也是遍历判断,注意这里写判断素数的自定义函数的时候,不要忘记输入的数可能是1和2,1和2一般要特殊处理

参考题解:

  1. #include <iostream>
  2. using namespace std;
  3. bool is_Prime(int n){ //判断是否为素数
  4. if(n == 1) return false;
  5. else if(n == 2) return true;
  6. for(int i = 2;i*i<=n;i++) if(n%i==0) return false;
  7. return true;
  8. }
  9. int main(){
  10. //问题 F: 判决素数个数
  11. int x,y,count = 0;cin >> x >> y;//count用于计数
  12. for(int i = x;i<=y;i++) if(is_Prime(i)) count++;
  13. cout << count << endl;
  14. return 0;
  15. }

问题 G: digit函数 

 

 思路:注意题目是从右往左找,直接循环整除10找即可

参考题解:

  1. #include <iostream>
  2. using namespace std;
  3. int find(int n,int k){ //实现找digit的函数
  4. int count = 1,temp = n;//count初始化为1,count代表从右往左第count个数字
  5. while(temp != 0){
  6. if(count == k) return temp%10;//先判断count是否等于k,count再++
  7. count++;
  8. temp /= 10;
  9. }
  10. }
  11. int main(){
  12. //问题 G: digit函数
  13. int n,k;cin >> n >> k;
  14. cout << find(n,k) << endl; //函数调用
  15. return 0;
  16. }

问题 H: 小数化分数1

相对其他题来说比较难,这里给出两种思路

思路1:以字符串形式读入小数,然后从小数点后开始构造分子和分母,特别地,此处后续对分子分母的约分直接调用头文件<algorithm>的__gcd()函数用于求最大公约数,其实像前面的题一样写一个gcd()函数也很快的

 参考题解1:

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstring>
  4. using namespace std;
  5. char ch[12];
  6. void transform(){
  7. int fenzi = 0, fenmu = 1;
  8. cin >> ch;
  9. for(int i = 2;i<strlen(ch);i++) {
  10. if (ch[i] >= '0' && ch[i] <= '9') {
  11. fenmu *= 10; //构造分母
  12. fenzi = fenzi * 10 + ch[i] - '0';//构造分子
  13. }
  14. }
  15. if (fenmu == 10 && fenzi == 0) {//如果输入0.0则输出0/1
  16. cout << "0/1" << endl;
  17. return;
  18. }
  19. //找最大公约数约分
  20. int _gcd = __gcd(fenmu,fenzi);
  21. fenmu = fenmu / _gcd;
  22. fenzi = fenzi / _gcd;
  23. cout << fenzi << "/" << fenmu << endl;
  24. }
  25. int main() {
  26. //问题 H: 小数化分数1
  27. int n;
  28. cin >> n;
  29. getchar();//读掉最后的换行符
  30. while(n--) transform();
  31. return 0;
  32. }

思路2:以双精度浮点数double的形式读入数据,根据题意小数位不会超过9位,构造分母为1e9,构造分子为数据乘以1e9,但是注意此处分子的构造会丢失精度,需要在乘以1e9后再加上0.5解决精度丢失问题,然后约分输出即可

参考题解2:

  1. #include <iostream>
  2. using namespace std;
  3. int gcd(int x,int y){ //求最大公约数函数
  4. int temp;
  5. if(x<y){ //确保x>y
  6. temp = x;
  7. x = y;
  8. y = temp;
  9. }
  10. while(x%y != 0){ //辗转相除法求最大公约数
  11. temp = x%y;
  12. x = y;
  13. y = temp;
  14. }
  15. return y;
  16. }
  17. int main(){
  18. //问题 H: 小数化分数1
  19. int n;cin >> n;
  20. double dec;
  21. int num;
  22. while(n--){
  23. cin >> dec;
  24. num = dec*1000000000+0.5; //+0.5是为了解决精度丢失的问题
  25. if(num==0) cout << "0/1" << endl;//num为0输出“0/1”
  26. else{
  27. int gcdnum = gcd(1000000000,num);//找num和1e9的最大公约数
  28. cout << num/gcdnum << "/" << 1000000000/gcdnum << endl; //输出的时候,分子分母同时除以最大公约数
  29. }
  30. }
  31. return 0;
  32. }

问题 I: 字符串匹配 

 

又算一个难题,难点在字符匹配这一个阶段

思路:操作1比较好处理,注意刚开始给buf[]数组长度时尽可能大一些,将两个字符串通过下标(索引)拼接;操作3是最好处理的,我们都知道数组遇到'\0'会认为已经到头了,我们只需计算数组buf长度与len的差,直接找到对应下标,修改值为'\0';操作2是匹配字符串,最好写一个函数,我这里匹配的思路是暴力匹配

参考代码:

  1. #include <iostream>
  2. #include <cstring>
  3. using namespace std;
  4. int lenbuf,lens;
  5. void match(char buf[10005],char s[105]){ //字符串匹配
  6. lenbuf = strlen(buf);lens = strlen(s);
  7. int maxk = 0;
  8. for(int i = 0;i<lenbuf;i++){ //暴力匹配
  9. for(int j = 0;j<lens;j++){
  10. int k;
  11. for(k = 0;k<lens;k++){ //如果buf[i+k]和s[j+k]对应都相等,k++
  12. if(buf[i+k] != s[j+k]) break;
  13. if(buf[i+k] == '\0') break;
  14. }
  15. if(k > maxk) maxk = k; //求出所有k中最大的那个k,就是我们要找的值
  16. }
  17. }
  18. cout << maxk << endl;
  19. }
  20. int main(){
  21. //问题 I: 字符串匹配
  22. char buf[10005],s[105];
  23. int m,op,len;
  24. while(~scanf("%s",buf)){//~scanf() 等价于 scanf()!=EOF 也等价于 scanf() == 1
  25. cin >> m;
  26. while(m--){
  27. cin >> op; //op为操作数:1或2或3
  28. if(op == 1){
  29. lenbuf = strlen(buf);
  30. cin >> s;
  31. lens = strlen(s);
  32. for(int i = 0;i<lens;i++) buf[lenbuf+i] = s[i];//拼接字符串
  33. buf[lenbuf+lens] = '\0';//找到buf的新长度,输入结束符'\0'
  34. }else if(op == 2){
  35. cin >> s;
  36. match(buf,s); //调用函数
  37. }else if(op == 3){
  38. cin >> len;
  39. lenbuf = strlen(buf);
  40. buf[lenbuf-len] = '\0'; //直接用结束符'\0'截断即可
  41. }
  42. }
  43. }
  44. return 0;
  45. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/426292
推荐阅读
  

闽ICP备14008679号