賽碼網編程題--「股神」

昨天看到了賽碼在線編程的一道題,熱度很高。賽碼-股神
題目是這樣的:node

clipboard.png

漲一天,跌一天,漲兩天,跌一天....看似頗有規律,看似很簡單。但昨天嘗試了一下,發現仍是有點麻煩,由於他的數據範圍很大(10^9),絕對不能再嵌套循環!
而後我翻了下大神們的答案。。。給大神跪了。。。編程

大神們的解法

var cmd = require('node-stdio');

var func = (n) => {
    let i = 0,
        k = 2,
        j = 2;
    while(k < n) {
        i = i + 2;
        j = j + 1;
        k = k + j;
    }

    return n - i;
}

var line;
while((line=cmd.readInt()) != null){
    cmd.print(func(line));
}

簡單易懂的方法

以上是最高票的答案。。。講道理我沒怎麼看懂。。。反正膜拜就對了
贊數靠前的大神們,基本也是像這樣用數學方法算的。
但我以爲這種方法不易懂,至少不適合我。
那有沒有更簡單的方法呢?今天又琢磨了一下,想到了一個超簡單的方法,忽然感受成就感max哈哈。
個人解法的核心思想就是圖形化,把抽象具體化。優化

漲一天,跌一天,漲兩天,跌一天,將這種狀態具體化記錄下來,能夠這樣:10110 。聰明的你確定懂了,下面直接上代碼ui

const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    terminal:false
})

rl.on('line', (line) => {
    let n = +line.trim()
    let mark = '1', res = 1
    for(let i=0, k=1; mark.length < n; i++) {
      let ans = Math.min(k,n - mark.length)
      if(i%2 == 1) {
        mark += 0
        res--
      } else {
        mark += '1'.repeat(ans)
        res += ans
        k++
      }
    }
    console.log(res)
})

甚至都不須要記錄這個狀態字符串,由於他只須要最終的價格,因此優化後代碼以下:spa

const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    terminal:false
})

rl.on('line', (line) => {
    let n = +line.trim()
    let day = 1, res = 1 //mark是Number類型就能夠了,表明第幾天
    for(let i=0, k=1; day < n; i++) {
      let ans = Math.min(k,n - day)
      if(i%2 == 1) {
        day++
        res--
      } else {
        // mark += '1'.repeat(ans)
        day += ans
        res += ans
        k++
      }
    }
    console.log(res)
})
相關文章
相關標籤/搜索