PAT 1005 继续(3n+1)猜想 25分 知识点:打表找规律

109 阅读1分钟

题目:1005 继续(3n+1)猜想 - PAT (Basic Level) Practice (中文) (pintia.cn)

解析:5_哔哩哔哩_bilibili

首先我们输入的样例全部按3n+1猜想输出一下,看一下为什么7,6会是答案:

我们发现只有输入的x值6,7只出现了一次,其余输入的x值都被包含在其他解中: image.png

因此我们可以用哈希思想,在解的过程中没有找到输入的x值,那这个x值就是我们要找的答案。

数组哈希

#include<bits/stdc++.h>
using namespace std;
vector<int>ans;
int a[110];
int haxi[10005];
int main()
{
    int n;cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
        int x=a[i];
        while(x!=1)
        {
        if(x%2)x=3*x+1,x/=2;
        else x=x/2;
        haxi[x]=1;            
        }
    }

    for(int i=0;i<n;i++)
    {
        if(!haxi[a[i]])
        ans.push_back(a[i]);
    }

    sort(ans.begin(),ans.end(),greater<int>());
    for(int i=0;i<ans.size();i++)
    {
        if(i)cout<<" "<<ans[i];
        else cout<<ans[i];
    }
    return 0;
}

image.png

map哈希

#include<bits/stdc++.h>
using namespace std;
vector<int>v;
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int n=0;cin>>n;
     v.resize(n);
 vector<int>ans;
      
    map<int,int> m;
    
    for(int i=0;i<n;i++)
    {
        
        cin>>v[i];
         int temp =v[i];
        m[temp]++;

        while(temp!=1)
        {
            if(temp%2)
            {
                temp=(temp*3+1)/2;
            }
            else
            {
                temp=temp/2;
            }   m[temp]++;
        }
     
    }

   
   for(int i=0;i<v.size();i++){
        if(m[v[i]]==1) ans.push_back(v[i]);
        //如果本数字被遍历的次数仅为一次,说明这个数字是关键数字,将其压入到result数组中
    }

    sort(ans.begin(),ans.end(),cmp);
   for(int i=0;i<ans.size();i++){
        if(i!=0)    cout<<" ";      //用于表示数字间用 1 个空格隔开,但一行中最后一个数字后没有空格。
        cout<<ans[i];
    }
    return 0;
}

image.png image.png