当前位置:   article > 正文

【NOIP】数字反转题解(含取整数各个位的常用算法思路)_1060: 数字反转noip

1060: 数字反转noip

author:&Carlton

tags:模拟,字符串

topic:【NOIP】数字反转题解(含取整数各个位的常用算法思路)

language:C++

website:洛谷

date:2023年7月20日


目录

题目介绍

我的题解

其他优秀题解:

反思


题目介绍

        

 

我的题解

        

        还是经典的数字取位逐步取位并输出,利用输出顺序完成数字反转(即不依靠数组存储数值直接输出,简化步骤)

        在这个过程一定要留意题目要求(也是模拟题的特点),区别正负数、去掉高位非法0。

        下次注意的点:

        ①“%”运算符两侧需要int数据类型。pow函数返回值是double,与N参与四则运算也会是double,所以要先转换数据类型。

        ②pow函数在cmath或math.h头文件都可以

        ③题意不要理解错了/漏了,写完算法可以具特殊例子先简单跑一下,看看符不符合要求,同时多考虑特殊情况,比如:区别正负数、去掉高位非法0(-32,100)

        本题容易漏的点:

        ①非法0有可能由原数连续的低位0造成,都需要统一解决。

        ②负数最好一开始就转换为正数处理,不然每次运算得到的结果都会带有负号。

        可以添加的优化:

        对连续0的处理,在一开头就加上↓

        while(N%10==0) N/=10;

        吐槽一下:曲折,2次CE,3次WA,最后才AC,但其实蛮简单的,注意细节就好,而且一定要关注刚开始的算法设计环节,也要熟悉代码语法规则(多敲,多报错,从错误中学习hh

源代码:        

  1. #include <iostream>
  2. #include <cmath>//用到pow函数
  3. using namespace std;
  4. int main()
  5. {
  6. int N;
  7. cin >> N;
  8. int a,i;
  9. if(N==0)
  10. {
  11. cout << 0 << endl;
  12. return 0;
  13. }
  14. //是0直接打印0结束,不是那就继续运行程序
  15. else
  16. {
  17. if(N<0)
  18. {
  19. cout << '-'; //是负数就先打印负号,然后转换为正数处理
  20. N=-N;
  21. }
  22. for(i=0;N/(int)pow(10,i)!=0;i++) //%运算符两侧需要都为int类型
  23. {
  24. if(i==0 && N/(int)pow(10,i)%10==0)
  25. {
  26. do
  27. {
  28. i++;
  29. }while(N/(int)pow(10,i)%10==0);
  30. //防止打印非法首位0(要囊括原数低位连续0的情况,如100)
  31. }
  32. cout << N/(int)pow(10,i)%10; //注意没有endl干扰,每次只打印一个数据
  33. }
  34. //通过打印顺序来实现数字反转
  35. }
  36. return 0;
  37. }

        

其他优秀题解:

        

        一些思路: 

        ①还是取位,但是结合运算后用数组存数,存的是一个整体,然后整体输出

        ②通过抛数位、让位直接操作,十分快速(喜欢这类,很直接、方便)

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int n; cin>>n; //反转之前的数
  6. if(n<0) {cout<<"-";n=-n;} //不管正负数,都转成正数方便操作。如果是负数,先输出一个"-"
  7. while(n%10==0) {n=n/10;} //如果一个数的最后一位为0,去掉不看
  8. int sum=0; //反转之后的数
  9. while(n!=0)
  10. {
  11. int k=n%10;
  12. sum=sum*10+k; //sum*10+k的意思是在原数sum的基础上拓展一个个位并存储k(有点像栈的操作)
  13. n=n/10; //去掉一位
  14. }
  15. cout<<sum<<endl;
  16. return 0;
  17. }

       

    ③还可以用字符串,输入的123不仅可以作为一个数字存在,也可以直接传入字符串类型:

        利用字符串相关的运算法则和函数来解决问题(还没学,应该和重载运算符和字符串专题即常用字符串函数有关)        

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. string s1,s2;
  4. int main(){
  5. cin>>s1;
  6. if(s1[0]=='-')
  7. {
  8. cout<<"-";//输出负号
  9. for(int i=s1.length()-1,j=0;i>=1;i--,j++) s2=s2+s1[i];//倒着变成正的
  10. if(s2[0]=='0') s2.erase(0,s2.find_first_not_of('0'));//去0
  11. cout<<s2;//输出
  12. }
  13. else //否则为正
  14. {
  15. for(int i=s1.length()-1,j=0;i>=0;i--,j++) s2=s2+s1[i];//正着倒序
  16. if(s2[0]=='0')s2.erase(0,s2.find_first_not_of('0'));//删除0
  17. cout<<s2;//输出
  18. }
  19. return 0;
  20. }

        ④,应该说的是一种编程思想,但本题解有结合字符串的使用。    

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. char a[100001];
  4. int t=0;
  5. int main()
  6. {
  7. string b,c;
  8. bool sign=false,f=false;
  9. cin>>c;
  10. for(int i=0;i<=c.length();i++)
  11. {
  12. if(c[i]=='-') s=true;
  13. else a[++t]=c[i];
  14. }
  15. if(s==true) b+="-";
  16. t--;
  17. for(t;t>=0;t--)
  18. {
  19. if(a[t]!='0'&&f==false) f=true,b+=a[top];
  20. else if(f==true) b+=a[t];
  21. }
  22. int i=atoi(b.c_str());//字符串转换为整数
  23. cout<<i;
  24. return 0;
  25. }

反思

        

        ①在处理取数位的问题时,好好利用“%”和“/”两个运算符,效率高。

        ②可以对输入的数据本身进行处理,这样更直接,不一定都得从侧面入手与输入的数据搭配,如果需要原始数据在开头保存就可以了

        比如我自己在循环体中用“N/(int)pow(10,i)!=0”作为判断条件,忽略了对数据本身直接处理能够更方便地得到有效数据,如优秀题解2的k,sum等。

        也就是说我的题解还有个优化方向:用N=N/10代替pow函数来辅助完成取位操作

欢迎指正与分享,谢谢!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/程序语言诗人/article/detail/60508?site
推荐阅读
相关标签
  

闽ICP备14008679号