進階與經典題目


Posted by 小小碼農 on 2021-05-02

所有題目皆可忽略前面,直接從 functon solves(){} 開始看就好

Q1 好多星星

輸入為一個數字 N,請按照規律輸出正確圖形

N=1

*
N=2

*
**
N=3

*
**
***
....

N=10

*
**
***
****
*****
******
*******
********
*********
**********

輸入為一個正整數 N,1 <= N <= 301<=N<=30,請依照規律輸出正確圖形

Q1 解題

var readline = require("readline");
var rl = readline.createInterface({
  input: process.stdin,
});

var lines = [];

// 讀取到一行,先把這一行加進去 lines 陣列,最後再一起處理
rl.on("line", function (line) {
  lines.push(line);
});

// 輸入結束,開始針對 lines 做處理
rl.on("close", function () {
  solve(lines);
});

// 上面都不用管,只需要完成這個 function 就好,可以透過 lines[i] 拿取內容
function solve(lines) {
  printStars(Number(lines[0]));
}

function printStars(n) {
  let stars = "";
  for (let i = 1; i <= n; i++) {
    stars += "*";
    console.log(stars);
  }
}

Q1 解題思路

  1. 對於累加的東西,想到迴圈
  2. 使用空字串累加,每跑一次加一次星星

Q2 水仙花數

水仙花數(Narcissistic number)又被稱為自戀數或者是阿姆斯壯數,太數學的定義我們就不講了,詳情可以查維基百科。
比較白話的定義為:「一個 n 位數的數字,每一個數字的 n 次方加總等於自身」
例如說 153 是三位數,而 1^3 + 5^3 + 3^3 = 153, 所以它就是一個水仙花數
而 1634 是四位數,而 1^4 + 6^4 + 3^4 + 4^4 = 1634, 所以它也是一個水仙花數
而數字 0~9 也都是水仙花數,因為一位數 n 的 1 次方一定會等於自己
現在給你一個範圍 n 到 m,請你求出這範圍之中的水仙花數有哪些

輸入為兩個用空白分割的正整數 N 與 M,1 <= N <= M <= 10^6
請由小到大輸出從 N 到 M(包含 N 與 M)有哪些水仙花數,每個數字以空行分隔

Sample Input 1
5 200
5
6
7
8
9
153

Q2 解題

var readline = require("readline");
var rl = readline.createInterface({
  input: process.stdin,
});

var lines = [];

// 讀取到一行,先把這一行加進去 lines 陣列,最後再一起處理
rl.on("line", function (line) {
  lines.push(line);
});

// 輸入結束,開始針對 lines 做處理
rl.on("close", function () {
  solve(lines);
});

// 上面都不用管,只需要完成這個 function 就好,可以透過 lines[i] 拿取內容
function solve(lines) {
  let temp = lines[0].split(" ");
  let n = Number(temp[0]);
  let m = Number(temp[1]);

  for (let i = n; i <= m; i++) {
    if (isNarcissistic(i)) console.log(i);
  }
}

// 判斷位數
function digitsCount(n) {
  let result = 0;
  if (n === 0) return 1;
  while (n !== 0) {
    n = Math.floor(n / 10);
    result++;
  }
  return result;
}

function isNarcissistic(n) {
  // 幾位數
  let m = n;
  let digits = digitsCount(m);
  let sum = 0;
  while (m !== 0) {
    let num = m % 10;
    sum += num ** digits;
    m = Math.floor(m / 10);
  }
  return sum === n;
}

Q2 解題思路

  1. 先讀取題目提供的參數,n, m,分別設為迴圈的起始及終止條件,迴圈內寫個判斷式,帶入 isNarcissistic(),若為 true,就印出

  2. 先判斷位數才有依據去計算是否符合 isNarcissistic()

  3. 計算位數的部分,設定 result = 0,再來先處理 edge case,0 是一位數,接著就是把這個數不斷除 10 再無條件捨去,每執行一次 result 就加一,直到這個數無法再被 10 除,回傳 result 就能知道是幾位數

  4. isNarcissistic() 部分,先宣告變數 m = n,留著最後檢驗這個數本身是否相等位數相加結果時使用,再來帶入位數運算,得知了是幾位數,先假定 sum = 0,sum 每次會加最後一位數的位數次方,而要得知最後一位數是什麼,就會使用 %,每次 % 10,接著再將此數除 10,再無條件捨去,如此重複,直到 m = 0

  5. 使用三元運算子檢驗 sum 是否等於 n,是,回傳 true,否,回傳 false


Q3 判斷質數

質數的定義為:在大於 1 的自然數中,除了 1 和該數自身以外,無法被其他自然數整除的數。

換句話說,如果一個大於 1 的正整數的因數除了 1 和自己以外就沒有其他的了,那就是質數,以下是前 10 個數字的因數:

1: 1
2: 1, 2
3: 1, 3
4: 1, 2, 4
5: 1, 5
6: 1, 2, 3, 6
7: 1, 7
8: 1, 2, 4, 8
9: 1, 3, 9
10: 1, 2, 5, 10

根據因數可得知,1~10 的質數為:2, 3, 5, 7

現在給你一些數字,請輸出每一個數字是否為質數

Sample Input 1
5
1
2
3
4
5
Sample Output 1
Composite
Prime
Prime
Composite
Prime

Q3 解題

var readline = require("readline");
var rl = readline.createInterface({
  input: process.stdin,
});

var lines = [];

// 讀取到一行,先把這一行加進去 lines 陣列,最後再一起處理
rl.on("line", function (line) {
  lines.push(line);
});

// 輸入結束,開始針對 lines 做處理
rl.on("close", function () {
  solve(lines);
});

// 上面都不用管,只需要完成這個 function 就好,可以透過 lines[i] 拿取內容
function solve(lines) {
  const n = Number(lines[0]);
  const arr = [];
  for (let i = 1; i <= n; i++) {
    arr.push(Number(lines[i]));
  }
  for (let i = 0; i < n; i++) {
    console.log(isPrime(arr[i]) ? "Prime" : "Composite");
  }
}

function isPrime(n) {
  const mid = Math.sqrt(n);
  if (n === 1) return false; // edge case
  for (let i = 2; i <= mid; i++) {
    if (n % i === 0) return false;
  }
  return true;
}

Q3 解題思路

  1. 先將範圍內的數使用陣列處理好,接著只要檢驗這範圍內的數是否符合條件。

  2. 將範圍內的每一個數都使用迴圈去除,只要出現除了 1 與自己以外的數,就回傳 false,否則回傳 true,這邊也運用三元運算子,簡潔許多。

  3. isPrime() 中先將 edge case 獨立出來處理,迴圈再從 2 開始跑,一個一個檢驗,但全部完會耗時太久,這邊做個數學小處理,把要運算的數字都先開根號,因為一個數若有因數,除了 1 與自己,其他必定是對稱的,後面因數會重複,就不用查了。

心得 :

  • isPrime() 內只會回傳布林值,這點提醒自己這時候就要好好遵守,免得之後亂掉,畢竟函式都叫 isPrime() 了。

Q4 判斷迴文

迴文的定義很簡單,就是你把一個字串倒過來以後還是長的跟原字串一樣
舉例來說,aba 倒過來還是 aba,我們就稱 aba 為迴文
abab 倒過來變成 baba,跟原本的字串不一樣,就不是迴文

現在給你一個字串 S,請輸出 S 是否為迴文

一個字串 S, 1 <= length(S) <= 100,

若是迴文請輸出 True,否之則輸出 False

Sample Input 1 
abbbba
Sample Output 1
True
Sample Input 2
ac
Sample Output 1
False

Q3 解題

var readline = require("readline");
var rl = readline.createInterface({
  input: process.stdin,
});

var lines = [];

// 讀取到一行,先把這一行加進去 lines 陣列,最後再一起處理
rl.on("line", function (line) {
  lines.push(line);
});

// 輸入結束,開始針對 lines 做處理
rl.on("close", function () {
  solve(lines);
});

// 上面都不用管,只需要完成這個 function 就好,可以透過 lines[i] 拿取內容
function solve(lines) {
  let str = lines[0]; // abbbba
  console.log(reverse(str) === str ? "True" : "False");
}

function reverse(str) {
  let result = "";
  for (let i = str.length - 1; i >= 0; i--) {
    result += str[i];
  }
  return result;
}

Q4 解題思路

  1. 想到如果要倒著檢查,只要把迴圈的終止條件變成起始,起始變成終止條件,每次減一,就能實現。

  2. 一樣使用空字串,一個字一個字推進去,如果最後推完,長得跟要檢驗的字串一樣,那就回傳 True,否則就是 False。


Q5 聯誼順序比大小

幸好有你的幫忙,小明順利地搶下了聯誼的門票,準備迎接即將到來的聯誼!

班長跟其他幾個康輔社的同學為了這次聯誼準備了許久,希望能帶給對方班級一個良好的印象,也希望能在這次聯誼當中玩得愉快。

而這種聯誼的活動流程,第一個通常都是自我介紹或是玩團康遊戲,像是大家好或者是廣東炒麵之類的。這次的聯誼也不例外,第一個活動就是讓大家輪流自我介紹。

不要小看自我介紹這回事,順序可是很重要的!

若是本身的氣場就很強倒是無所謂,第一個登場可以震驚四方,最後一個登場的話也能夠幫自介環節劃下完美的句點。但如果沒有那麼擅長自我介紹的話,順序就有很大的差別了。

舉例來說,不太擅長說話的小明若是排在了氣場強大的康輔社活動咖同學後面,就會顯得特別弱,因為那個反差太明顯了。但若是小明排在其他也沒那麼會說話的同學後面,就不會顯得特別有問題,這就叫做藏拙,要盡量避免與太厲害的人做比較,否則一開場就輸了。

為了決定自我介紹的順序,班長決定來玩比大小

A 跟 B 兩個人會各自挑好一個數字,挑好以後就不能更改了,接著班長會說要比大還是比小

說完之後兩個人同時講出自己挑好的數字,根據比大或是比小來決定勝負

班長把每一組挑的數字以及比大比小寫在一張紙上,現在請你根據紙上面的輸入,輸出最後比賽的結果

輸入第一行會是一個數字 M,1 <= M <= 50,代表一共有幾組比賽的結果

接著每一行會有三個用空白分隔的數字 A, B, K

A 代表 A 選擇的數字,B 代表 B 選擇的數字,兩者皆保證為正整數
要特別注意的是 A 與 B 可能是很大的數字,但保證長度為 512 個位數以內

K 只會有兩種情況:1 或是 -1,若是 1 代表數字大的獲勝,K 若是 -1 代表數字小的獲勝

針對每一筆輸入,請輸出贏家是誰。

若是 A 贏請輸出 A,B 贏請輸出 B,平手則輸出 DRAW

Sample Input 1
3
1 2 1
1 2 -1
2 2 1
Sample Output 1
B
A
DRAW

Q5 解題

var readline = require("readline");
var rl = readline.createInterface({
  input: process.stdin,
});

var lines = [];

// 讀取到一行,先把這一行加進去 lines 陣列,最後再一起處理
rl.on("line", function (line) {
  lines.push(line);
});

// 輸入結束,開始針對 lines 做處理
rl.on("close", function () {
  solve(lines);
});

// 上面都不用管,只需要完成這個 function 就好,可以透過 lines[i] 拿取內容
function solve(lines) {
  const m = Number(lines[0]);
  for (let i = 1; i <= m; i++) {
    console.log(getWinner(lines[i]));
  }
}

function getWinner(set) {
  const [a, b, result] = set.split(" ");

  if (BigInt(a) === BigInt(b)) {
    return "DRAW";
  } else if (
    (BigInt(a) > BigInt(b) && Number(result) === 1) ||
    (BigInt(a) < BigInt(b) && Number(result) === -1)
  ) {
    return "A";
  } else {
    return "B";
  }
}

Q5 解題思路

  1. 看到題目中「 要特別注意的是 A 與 B 可能是很大的數字,但保證長度為 512 個位數以內 」就知道說這要特別處理,也得知可以使用 BigInt() 這個內建函式

  2. 設定 m 為幾筆資料,使用迴圈,有幾筆資料就跑幾次

  3. 在每筆資料中,都會有三個元素,分別存進 [a, b, result] 中,

  4. 分成兩種情況想

  • A === B 平手
    • 就看分數一樣,就回傳 DRAW
  • A 或 B 贏
    • A 贏:
      1. A > B,且 Number(result) === 1
      2. A < B,且 Number(result) === -1
    • B 贏:
      1. A < B,且 Number(result) === 1
      2. A > B,且 Number(result) === -1

#javascript







Related Posts

CSS 預處理

CSS 預處理

Auto Generate Insert Script without SQL Manager

Auto Generate Insert Script without SQL Manager

Node.js Advanced Interview Questions for Experienced Professionals

Node.js Advanced Interview Questions for Experienced Professionals


Comments