1. 程式人生 > >問題 B: 第N個智慧數

問題 B: 第N個智慧數

問題 B: 第N個智慧數

題目描述
一個正整數如果能表示成了兩個正整數的平方差,則稱這個數為“智慧數”,比如16就等於5的平方減去3的平方,所以16就是一個智慧數,從1開始的自然數列中,將“智慧數”從小到大編號為1,2,3,„„,n。現輸入一個正整數n,輸出第n個“智慧數”。
輸入
僅包含一個正整數 n(1≤n≤100)。
輸出
僅包含一個正整數,表示編號為 n 的智慧數。
樣例輸入
3
樣例輸出
7
思路:因式分解找到是否是智慧數的判斷條件
若滿足x=a²-b²=(a+b)*(a-b)則x是一個智慧數。
設a-b=i
則a+b最小為(i+1)+1=i+2 x=(i+2)*i=i²+2i
再往後是 (i+2)+(1+1)=i+4 x=(i+4)*i=i²+4i
(i+n)+n=i+2n x=(i+2n)*i=i²+2ni (n是大於0的整數)

對於任意大於0的i x=i²+2ni
若i為奇數 則ii為奇數 2ni為偶數,偶數+奇數=奇數 即所有i為奇數時的智慧數必定為奇數
若i為偶數 則i
i為4的倍數 2ni為4的倍數 即所有i為偶數時的智慧數必定為4的倍數

當i=1時 x=1+2n 所以所有大於3的奇數全是智慧數
當i=2時 x=4+4n 所以所有大於8而且是4的倍數的都是智慧數

/************************************************************************************************/
其實思考的思路是先證明出了大於3的奇數都是智慧數和大於8的4的倍數都是智慧數,然
後通過證明所有智慧數必定為奇數或者是4的倍數來證明不滿足上述條件的數都不是智慧
數。
/************************************************************************************************/
綜上,若x為智慧樹,則一定滿足x為大於3的奇數或者x為大於8的四的倍數

#include<iostream>
using namespace std;
int main()
{
    int n;//p存大於3的奇數,q存大於8的4的倍數
    cin>>n;
    int p=3,q=8;
    int s=0,ans=0;
    while(s!=n)
    {
        if(p<q)
        {
            ans=p;
            p+=2;
            s++;
        }
        else
        {
            ans=q;
            q+=4;
            s++;
        }
    }
    cout<<ans<<endl;
    return 0;
}

每四個數分為一個區間,第一個區間[1,4]第二個[5,8]依次類推
把每個區間的智慧數記錄下來
{3},{5,7,8},{9,11,12},{13,15,16},{17,19,20} …
每個區間必定有兩個奇數和一個4的倍數
所以除了第一個區間之外,別的區間都有三個智慧數
所以前N(N>1)個區間的智慧數個數為:1+3*(N-1)
若第n個智慧數包含前N個區間的所有智慧數,N取最大值,r表示N區間之外的智慧數個數
N=(n-1)/3;
r=n-1-3*N;

若n等於0,則第n個智慧數恰為第N個區間的最後一個智慧數即N*4+4
若n=1,則n為第n+1個區間的第一個智慧數即(N+1)*4+1
若n=2,則n為第n+1個區間的第二個智慧數即(N+1)*4+3

#include<iostream>
using namespace std;
int main()
{
    int n;
    cin>>n;
    if(n==1)
    {
        cout<<"3"<<endl;
    }
    else if(n==2)
    {
        cout<<"5"<<endl;
    }
    else  
    {
        int N,r;
        N=(n-1)/3;
        r=n-1-3*N;
        int a[3]={N*4+4,(N+1)*4+1,(N+1)*4+3};
        cout<<a[r]<<endl;
    }
    return 0;
}