解题思路:
题目中蕴含了一个隐藏的条件,那就是拼接的数是有两段数字构成的,那么就可以通过拆分的方式变成两端不同的字串进行操作。
判断思路如下:
去除无法拆分成两端数字的数(十位数一下,个位数没法拆)
去除 自身开放后不是整数的数字(注意,本体中判断自身开方是否是整数用到了一个取巧的操作)
floor(sqrt(i)+0.5)!=sqrt(i)
floor为向下取整,sqrt为开方,一个数字开方后加上0.5后向下取整,如果等于其开方后的自己则自己的开方数字为整数。这是一种无视类型直接求出需求的方法,此外这个取巧的办法还同样使用与一些判断计算结果是否有小数的计算,相当于一种计算上面的取巧,同样的方法有很多,本题其他题解就有各种方法。
3.利用整形转换字符串,字符串转换整形的操作,将整个数字切割成不同的两串(同样的思路也可以直接按照每一位数字直接除和取余来获取,总之就是切割成两部分),对于这两部分,分别判断其是存在两者均为开方后为整数的数字(注意满足,任意一边不得为全0)
注意字符串转换整形,整形转换字符串等这类操作的函数,在不同的OJ上有的不能使用
详细请看代码。
参考代码:
#include<bits/stdc++.h> #define hh ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; bool is_check(int i) { char str[10]= {0}; sprintf(str,"%d",i); //itoa(i,str,10); //部分OJ不允许使用 int len=strlen(str); if(i<10) { //单位数字无法拆分 return false; } if(floor(sqrt(i)+0.5)!=sqrt(i)) { //去除自身不是平方 return false; } char left[10]= {0},right[10]= {0}; //拆分成左右两边 int l,r; //分别代表分割出来的两个数字 for(int k=0; k<len-1; k++) { int pos=0; //标记right的 left[k]=str[k]; left[k+1]='\0'; for(int l=k+1; l<len; l++) { right[pos++]=str[l]; } right[pos]='\0'; l=atoi(left); r=atoi(right); if(floor(sqrt(l)+0.5)==sqrt(l)&&floor(sqrt(r)+0.5)==sqrt(r)&&l!=0&&r!=0) { return true; } } return false; } int main() { hh; int n,m; while(cin>>n>>m) { for(int i=n; i<=m; i++) { if(is_check(i)) { cout<<i<<endl; } } } return 0; }
看来要护肝了
0.0分
2 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复