• 【UVALive 11549】


    题目链接: http://acm.hust.edu.cn:8080/judge/problem/viewProblem.action?id=28547

    题目大意:  给你两个整数n,k,让k不停平方,每次平方完取出前n位数,让你找到最大的前n位数。

    解题思路:    自己列几项就可以看出一定是一个循环。当发现有重复的出现时循环就结束。

                      本题解法好多。

    解法1,用sstream流和set函数,4494ms。

    View Code
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <set>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <sstream>
     7 using namespace std;
     8 
     9 int next(int n, int k)
    10 {
    11     stringstream ss;  /// streamstring通常用来做数据转换的,可将int,char,long long, double 和string相互转换
    12     ss << (long long)k*k;  /// 向ss中插入k*k
    13     string s=ss.str();    /// 拷贝流缓冲到一个string对象s中
    14     if(s.length()>n)  s=s.substr(0,n);
    15     stringstream ss2(s);  ///再将s转换成流ss2
    16     int ans;
    17     ss2 >> ans;  ///抽取ss2中的数据传递给ans,实现转换
    18     return ans;
    19 }
    20 
    21 int main()
    22 {
    23     int n, k, T;
    24     cin >> T;
    25     while(T--)
    26     {
    27         cin >> n >> k;
    28         set<int>s;
    29         int ans=k;
    30         while(!s.count(k))
    31         {
    32             s.insert(k);
    33             if(ans<k)  ans=k;
    34             k=next(n,k);
    35         }
    36             printf("%d\n",ans);
    37     }
    38     return 0;
    39 }

    解法2,因为stream流耗费太多时间,改成数组存储,1140ms。

    View Code
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <set>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <sstream>
     7 using namespace std;
     8 
     9 
    10 int next(int n, int k)
    11 {
    12     if(!k) return 0;
    13     int a[30], ans=0;
    14     long long  t=(long long)k*k;
    15     int num=0;
    16     while(t)
    17     {
    18         a[num++]=t%10;
    19         t/=10;
    20     }
    21     if(num<n) n=num;;
    22     for(int i=num-1; i>=num-n; i--)
    23     {
    24         ans=ans*10+a[i];
    25     }
    26     return ans;
    27 }
    28 
    29 
    30 int main()
    31 {
    32     int n, k, T;
    33     cin >> T;
    34     while(T--)
    35     {
    36         cin >> n >> k;
    37         set<int>s;
    38         int ans=k;
    39         while(!s.count(k))
    40         {
    41             s.insert(k);
    42             if(ans<k)  ans=k;
    43             k=next(n,k);
    44         }
    45         printf("%d\n",ans);
    46     }
    47     return 0;
    48 }

    解法3,刚刚已经提到了这是一个循环,我们可以假设两个小孩在这个循环跑到里跑,孩子2跑得快,孩子1跑得慢,当孩子2追上孩子1时循环结束。这就是floyd判圈算法,500ms。

    View Code
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <set>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <sstream>
     7 using namespace std;
     8 
     9 
    10 int next(int n, int k)
    11 {
    12     if(!k) return 0;
    13     int a[30], ans=0;
    14     long long  t=(long long)k*k;
    15     int num=0;
    16     while(t)
    17     {
    18         a[num++]=t%10;
    19         t/=10;
    20     }
    21     if(num<n) n=num;;
    22     for(int i=num-1; i>=num-n; i--)
    23     {
    24         ans=ans*10+a[i];
    25     }
    26     return ans;
    27 }
    28 
    29 int main()
    30 {
    31     int n, k, T;
    32     cin >> T;
    33     while(T--)
    34     {
    35         cin >> n >> k;
    36         int k1= k, k2=k, ans=k;
    37         do
    38         {
    39                    k1=next(n,k1);
    40                    k2=next(n,k2);  ans=max(ans,k2);
    41                    k2=next(n,k2);  ans=max(ans,k2);
    42                  }  
    43                 while(k1!=k2);
    44         printf("%d\n",ans);
    45     }
    46     return 0;
    47 }
  • 相关阅读:
    插入排序
    阅读书单 2012 8月至12月
    sed学习1
    sed入门(一直在改变系列2)
    linux find资料(一直在改变系列4)
    awk入门(一直在改变系列1)
    分治算法
    shell脚本知识点1(一直在改变系列3)
    选择排序(selection sort)
    英语单词循环记忆第一期(自学使用)
  • 原文地址:https://www.cnblogs.com/kane0526/p/2805096.html
Copyright © 2020-2023  润新知