[MZOJ]128.开方 解题报告

【絮叨】

本来以为是道水题,没成想,一日忘特判,一百变零分。

【题目描述】

定义函数 f(n)=⌊n  √ ⌋,f 1 (n)=f(n),f y (n)=f(f y−1 (n)) f(n)=⌊n⌋,f1(n)=f(n),fy(n)=f(fy−1(n))

对于某个特定的 n,你需要求出最小的 y 满足 f y (n)=1 fy(n)=1 。

由于你不是很擅长徒手开根号,只会二分法,因此如果开根号开到 6 次及以上的话,你会弃疗。

现在你手上有一台计算机,快用它求得这个问题的答案吧!

【输入格式】

输入文件名为 sqrt.in

多组数据,以 EOF 结束。

每组数据占一行,表示 n。

【输出格式】

输出文件名为 sqrt.out

对于每组数据,输出一行,一个整数 y,表示答案;或者一个字符串“TAT”,表示你弃疗了。

【数据规模与约定】

对于 100% 的数据,有1≤测试数据组数≤120,0≤n≤10 100  有1≤测试数据组数≤120,0≤n≤10100 。

请注意,本题只有一个测试点。

【题目大意】

就是给出一个数,给它一直开根号(是二次的哟),直到等于一,问要开多少次,超过6次就放弃了(包括六次),可以看出,如果这个数为0,就可以一直开下去,所以要特判一下。

代码里有注解,就不过多赘述了~

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll MAX=4294967296;//2的 5次方,最大极限嘛 
int main()
{
    string s;//因为最高有120位数字,存不下,所以用字符串存 
    while(cin>>s){//一直输入直到没有了 
        ll b=0,len=0;
        bool flag=0;
        for(int i=0;i<s.length();i++){//string下标从零开始 
            b=b*10+s[i]-'0';//把字符转为数字 
            if(b>MAX){
                flag=1;break;//如果已经超出边界了,就标记一下,下面的也就不用计算了 
            }
        }
        if(!flag&&b>0){//当没有超边界和b不为0时 
            while(b>1){
                b=sqrt(b);len++;//len记录次数 
            }
            if(len>5)printf("TAT\n");//大于等于6就弃疗 
            else printf("%lld\n",len);
        }
        else printf("TAT\n");//超出边界或等于0就弃疗 
    } 
    return 0;//结束啦 
 }
View Code

【结语】

之前我一直过不了,unsigned long long 类型和int 类型的比较,死活过不了,编译器没报错,OJ上过不了,全改成long long 就行了(困惑),以后注意点吧。

看我这么详细,点个赞再走吧(QWQ)。

posted @ 2021-03-01 15:48  cshhaha  阅读(129)  评论(0)    收藏  举报