1. 程式人生 > >毛學姐大戰學渣

毛學姐大戰學渣

毛學姐大戰學渣(2018.11.28)

題目傳送門
Description
又到了毛學姐屠殺學渣的時候了,學渣根據實力不同從 Lv1 依次向上提升,毛學姐每屠殺一個學渣就會不斷地提升自己的實力,從而挑戰更高等級的學渣,他按照這樣的方式屠殺學渣:1,1,2,1,1,1,3,1,1,1,1,4,1,1,1,1,1,5…1,1,2,1,1,1,3,1,1,1,1,4,1,1,1,1,1,5… 第一二天他屠殺2個Lv1Lv1的學渣,然後第三天能夠屠殺一個LV2LV2的學渣,接下來,毛學姐再殺33個LV1LV1的學渣【為了恢復體力】,然後殺死一個LV3LV3的學渣,如此往復。但是毛學姐數學不好,殺著殺著就忘了今天該輪到等級多少的學渣了,請你幫他計算一下。

Input
有多組測試樣例。輸入一個正整數數NN,代表要殺的第NN個學渣。(0<N<100000)(0<N<100000)

Output
輸出第NN個學渣的等級

Sample Input 1
1
18

Sample Output 1
1
5
題解
這個題剛剛看起來很簡單,AC的辦法有很多,但當真正寫起程式碼之後才會發現事情並非想象的那麼簡單。 我做這個題的時候先用了一些最淺的規律(每個高階學渣前都有一個與等級數量相等的一級學渣),但提交程式碼後顯示超時,無奈,我只好換了一種思路,用等差數列前n項和的求和公式(通過觀察可以發現,112 1113 11114 111115… …就是一個首項為3,公差為1的等差數列),很不幸,新的思路再一次因超時而被否決。於是我採用了最笨的方法:暴力打表(將毛學姐屠殺的前100000個學渣以陣列的形式列出來)多次調整之後終於AC。下面先看AC程式碼。

#include<stdio.h>
int main()
{
    int N,m=2,n,x=0;
    int l[110090];//①
    while(m<450)//②
    {
        for(n=0;n<m;n++)
        {
            l[x]=1;
            x++;
            if(m==n+1){l[x]=m;x++;}
        }
        m++;
    }
    while(scanf("%d",&N)!=EOF)
    {
        printf("%d\n",l[N-1]);
    }
    return 0;
}

註釋
①:這個數是根據下面的註釋②隨機取的,為保證②成立的隨機數。
②:剛開始我取的數是320(對100000開根號後取了一個稍大的數),提交後顯示WA,而後就往上隨機取數直到AC。之後問大佬才知道這個數是448,下面是原理:

s=0
a=3
while(s<100000):
    s=s+a
    a=a+1
print(a)

(s表示的是天數,a表示的是非1的等級)