[TOC] # 評測系統 https://cc.cysh.cy.edu.tw/problem # p0 簽到題_哈囉資研社!!! ## Description > 學習所有程式語言的第一個練習題 請寫一個程式,可以讀入指定的字串,並且輸出指定的字串。 > > 比如:輸入字串 "world", 則請輸出 "hello, world" ## Input Description > 輸入總共一行,內含一組文字 ## Output Description > 輸出題目指定的文字。 ## 範例程式碼 - python ```python= a=str(input()) print("hello, "+a) ``` - cpp ```cpp= #include <bits/stdc++.h> using namespace std; int main() { string a; cin >> a; cout << "hello, "+a << "\n"; } ``` - java ```java= import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin= new Scanner(System.in); String s; while (cin.hasNext()) { s=cin.nextLine(); System.out.println("hello, " + s); } } } ``` ## 範測 | 輸入 | 輸出 | | -------------- |:--------------------- | | CYSH | hello, CYSH | | 嘉義高中資研社 | hello, 嘉義高中資研社 | | world | hello, world | # p1 一元二次方程式 ## Description > 求一元二次方程式 ${ax^2 + bx + c = 0}$ 的根 ## Input Description > 每組輸入共一行,內含三個整數 a, b, c 以空白隔開,保證根為整數。${-100 \leq a, b, c \leq 100}$ ## Output Description > Two different roots x1=?? , x2=?? > > Two same roots x=?? > > No real root > > PS: 答案均為整數,若有兩個根則大者在前 ## 範例程式碼 - python ```python= import math a,b,c=map(int,input().split()) d = b * b - 4 * a * c if (d > 0): x1 = int((-b + math.sqrt(b * b - 4 * a * c)) // (2 * a)) x2 = int((-b - math.sqrt(b * b - 4 * a * c)) // (2 * a)) print(f"Two different roots x1={x1} , x2={x2}") elif (d == 0): x1 = int((-b + math.sqrt(b * b - 4 * a * c)) // (2 * a)) print(f"Two same roots x={x1}") else: print("No real root") ``` - cpp ```cpp= #include <bits/stdc++.h> using namespace std; int main() { int a, b, c, d; cin >> a >> b >> c; if(a==0){ cout << "No real root"; return 0; } d = b * b - 4 * a * c; if (d > 0 ) { cout << "Two different roots "; cout << "x1=" << max((-b + sqrt(d)) / (2 * a), (-b - sqrt(d)) / (2 * a)) << " , "<< "x2=" << min((-b + sqrt(d)) / (2 * a), (-b - sqrt(d)) / (2 * a)); } else if (d == 0 ) { cout << "Two same roots "; cout << "x=" << -b / (2 * a); } else cout << "No real root"; } ``` - java ```java= import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin= new Scanner(System.in); int a = cin.nextInt(); int b = cin.nextInt(); int c = cin.nextInt(); int d = (int) Math.pow(b,2)-4*a*c; if (d < 0) { System.out.println("No real root"); }else if (d == 0) { int answer = (-b)/(2*a); System.out.println("Two same roots x="+answer); }else { int answer1 = (int) (-b+Math.sqrt(d))/(2*a); int answer2 = (int) (-b-Math.sqrt(d))/(2*a); System.out.println("Two different roots x1="+answer1+" , x2="+answer2); } } } ``` ## 範測 | 輸入 | 輸出 | | ------- |:-------------------------------- | | 1 3 -10 | Two different roots x1=2 , x2=-5 | | 1 0 0 | Two same roots x=0 | | 1 1 1 | No real root | # p2 簡易成績等第換算 ## Description > 為了方便統計所有學員的成績分布,將原始成績轉換成等第 > > 若分數介於 ${90}$ 到 ${100}$(包括 ${90}$ 和 ${100}$),輸出 ${ \text{S} }$。 > > 若分數介於 ${80}$ 到 ${89}$(包括 ${80}$ 和 ${89}$),輸出 ${ \text{A} }$。 > > 若分數介於 ${70}$ 到 ${79}$(包括 ${70}$ 和 ${79}$),輸出 ${ \text{B} }$。 > > 若分數介於 ${60}$ 到 ${69}$(包括 ${60}$ 和 ${69}$),輸出 ${ \text{C} }$。 > > 若分數介於 ${50}$ 到 ${59}$(包括 ${50}$ 和 ${59}$),輸出 ${ \text{D} }$。 > > 若分數介於 ${40}$ 到 ${49}$(包括 ${40}$ 和 ${49}$),輸出 ${ \text{E} }$。 > > 其餘分數輸出 ${ \text{F} }$。 ## Input Description > 輸入一個正整數 ${ N }$ 代表學生的成績${ 0 \leq N \leq 100 }$。 ## Output Description > 輸出轉換後的等第標示 ## 範例程式碼 - python ```python= a = int(input()) if 90 <= a <= 100: print("S") elif 80 <= a <= 89: print("A") elif 70 <= a <= 79: print("B") elif 60 <= a <= 69: print("C") elif 50 <= a <= 59: print("D") elif 40 <= a <= 49: print("E") else: print("F") ``` - cpp ```cpp= #include<iostream> using namespace std; int main(){ int a; cin >> a; if(a>=90 && a<=100){ cout << "S"; } else if(a>=80 && a<=89){ cout << "A"; } else if(a>=70 && a<=79){ cout << "B"; } else if(a>=60 && a<=69){ cout << "C"; } else if(a>=50 && a<=59){ cout << "D"; } else if(a>=40 && a<=49){ cout << "E"; } else{ cout << "F"; } } ``` - java ```java= import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin= new Scanner(System.in); int score = cin.nextInt(); if(score>=90 && score<=100){ System.out.println("S"); } else if(score>=80 && score<=89){ System.out.println("A"); } else if(score>=70 && score<=79){ System.out.println("B"); } else if(score>=60 && score<=69){ System.out.println("C"); } else if(score>=50 && score<=59){ System.out.println("D"); } else if(score>=40 && score<=49){ System.out.println("E"); } else{ System.out.println("F"); } } } ``` ## 範測 | 輸入 | 輸出 | | ---- |:---- | | 60 | C | | 100 | S | # p3 基礎迴圈_最大公因數(GCD) ## Description > 給定兩個整數,請求出它們的最大公因數 ## Input Description > 輸入包含兩個整數,以空白鍵隔開,兩個整數均大於 0, 小於 $2^{31}$ ## Output Description > 輸出兩個整數的最大公因數 ## 範例程式碼 - python ```python= a, b = map(int, input().split()) r = 1 while r > 0: r = a % b a = b b = r print(a) ``` - cpp ```cpp= #include <iostream> using namespace std; int main(){ int a,b,r=1; cin >> a >> b; while(r>0){ r=a%b; a=b; b=r; } cout << a <<endl; } ``` - java ```java= import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin= new Scanner(System.in); int a = cin.nextInt(); int b = cin.nextInt(); int r = 1; while (r > 0) { r = a % b; a = b; b = r; } System.out.println(a); } } ``` ## hint 可以運用輾轉相除法呦! ![images](https://hackmd.io/_uploads/SJ0En4ZTA.png) ## 範測 | 輸入 | 輸出 | | ----- |:---- | | 12 15 | 3 | | 1 100 | 1 | # p4 進階條件判斷_時區判別 ## Description > [原題PDF檔](https://apcs-simulation.com/public/upload/529cbca30a.pdf) > > 大明博士發明了自製的傳送器,可以傳送到各種不同的星球上去探險,某一天他到訪一個星球,博士發現這個星球一天有著 ${36}$ 個小時,分鐘與秒數的規則與地球上一樣。博士為了方便將會以${36}$小時制來進行記錄。該星球被區分成為${24}$個時區,每一個時區之間會相差${1}$小時又${30}$分鐘。舉例來說,若博士所在的區域為${3}$時${0}$分${0}$秒,則以博士的位置向東移動一個時區,時間就會變成${4}$時${30}$分${0}$秒;但如果以博士的位置向西移動一個時區,時間就會變成${1}$時${30}$分${0}$秒。給定博士目前所在區域的時間,以及移動多少個時區,請你幫忙換算移動完畢後新地區的時間會是多少。 ## Input Description > 輸入第一行會含有四個整數 ${H}$、${M}$、${S}$、${T}$ (${0 \leq H \leq 35}$、${0 \leq M \leq 59}$、${0 \leq S \leq 59}$、${-24 \leq T \leq 24}$),整數間以空白間隔。${H}$ 代表的是該地區當前的小時數、${M}$ 代表的是該地區當前的分鐘數、${S}$ 代表的是該地區當前的秒數、${T}$ 代表的是相隔多少個時區。如果 ${T}$ 為負,則代表向西移動;如果 ${T}$ 為正,則代表向東移動。 ## Output Description > 請依照該星球的時間轉換規則,輸出轉換後的時間。格式如範例所示。 > > 配分說明: > > 此題目測資分成兩組,每組測資有多筆測試資料,需答對該組所有測試資料才能獲得該組分數,各組詳細限制如下。 > > 第一組(30 分):博士在轉換時區時不會跨到下一天,或是跨回上一天。 > > 第二組(70 分):無特別限制。 ## 範例程式碼 - python ```python= H, M, S, T = map(int, input().split()) time = T * (1 * 3600 + 30 * 60) Sec = H * 3600 + M * 60 + S newSec = Sec + time MaxSec = 36 * 3600 if newSec < 0: newSec += MaxSec elif newSec >= MaxSec: newSec -= MaxSec H = (newSec // 3600) % 36 M = (newSec % 3600) // 60 S = newSec % 60 print(f"{H}:{M:02d}:{S:02d}") ``` - cpp ```cpp= #include <bits/stdc++.h> using namespace std; int main() { int H, M, S, T; cin >> H >> M >> S >> T; int time = T * (1 * 3600 + 30 * 60); int Sec = H * 3600 + M * 60 + S; int newSec = Sec + time; int MaxSec = 36 * 3600; if (newSec < 0) { newSec += MaxSec; } else if (newSec >= MaxSec) { newSec -= MaxSec; } H = (newSec / 3600) % 36; M = (newSec % 3600) / 60; S = newSec % 60; cout << setfill('0') << H << ":" << setw(2) << M << ":" << setw(2) << S << endl; return 0; } ``` - java ```java= import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin= new Scanner(System.in); int h = cin.nextInt(); int m = cin.nextInt(); int s = cin.nextInt(); int d = cin.nextInt(); int time = (h*3600)+(m*60)+s; // 為了易讀性加了括號 final int unit = 3600+30*60; // final(java) = const(其他語言) final int max = 36*3600; time += unit*d; if (time < 0) { time += max; }else if (time >= max) { time -= max; } h = (time / 3600) % 36; m = (time % 3600) / 60; s = time % 60; System.out.println(String.format("%01d:%02d:%02d",h,m,s)); } } ``` ## 範測 | 輸入 | 輸出 | | ----------- |:-------- | | 3 00 00 1 | 4:30:00 | | 3 00 00 -1 | 1:30:00 | | 2 15 13 -9 | 24:45:13 | | 14 39 51 15 | 1:09:51 | # p5 進階一、二維陣列_電子畫布 ## Description > 有一個 ${H \times W}$ 的電子畫布,一開始數值都是 ${0}$ 代表未填色。接下來請模擬 ${N}$ 次畫筆操作。 > > 每次畫筆操作為選一個座標 ${ (r, c) }$ 停留 ${t}$ 秒,它會將曼哈頓距離 ${\leq t}$ 的區塊染上顏色 ${x}$。若有多個顏色重複填到相同區塊,顏色的數值會累加起來。 > > 請輸出 ${N}$ 次操作後的畫布狀態。 ## Input Description > 第一行輸入三個正整數 ${H}$, ${W}$, ${N}$ (${1 \leq H, W \leq 20, 1 \leq N \leq 100}$)。 > > 接下來有 ${N}$ 行,每一行有四個整數 ${r}$, ${c}$, ${t}$, ${x}$ (${0 \leq r < H, 0 \leq c < W, 0 \leq t \leq 20, 1 \leq x \leq 10}$)。 > > (60 分):${H = 1}$ > > (40 分):無限制 ## Output Description > 輸出畫布做 ${N}$ 次畫筆操作後的狀態。(請不要輸出行尾空白) ## 範例程式碼 - python ```python= H, W, N = map(int, input().split()) a = [[0 for _ in range(105)] for _ in range(105)] for _ in range(N): r, c, t, x = map(int, input().split()) for j in range(H): for k in range(W): if abs(j - r) + abs(k - c) <= t: a[j][k] += x for i in range(H): print(' '.join(str(a[i][j]) for j in range(W))) ``` - cpp ```cpp= #include<bits/stdc++.h> using namespace std; int main(){ int H,W,N; cin >> H >> W >> N; int r,c,t,x,a[105][105]= {0}; while(N--){ cin >> r >> c >> t >> x; for (int j=0;j<H;j++){ for(int k=0;k<W;k++){ if(abs(j-r)+abs(k-c)<=t){ a[j][k]+=x; } } } } for(int i=0;i<H;i++){ for(int j=0;j<W;j++){ cout << a[i][j] ; if(j+1<W){cout << " ";} } cout << "\n"; } } ``` - java ```java= import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin = new Scanner(System.in); int h = cin.nextInt(); int w = cin.nextInt(); int n = cin.nextInt(); int[][] canvas = new int[h][w]; // new an array full of 0s for (int _i=0;_i<n;_i++) { int r = cin.nextInt(); // x int c = cin.nextInt(); // y int t = cin.nextInt(); // time(radius) int x = cin.nextInt(); // color for (int i=0;i<h;i++) { for (int j=0;j<w;j++) { if (Math.abs(i-r)+Math.abs(j-c)<=t) { canvas[i][j] += x; } } } } for (int i=0;i<h;i++) { for (int j=0;j<w;j++) { System.out.print(canvas[i][j] + (j==w-1?"":" ")); } System.out.println(); } } } ``` ## hint 以範測2為例 經過操作3 2 2 1後,畫布為 ![ShowImage](https://hackmd.io/_uploads/Skc9HuepR.png) 經過操作1 6 1 2後,畫布為 ![ShowImage (1)](https://hackmd.io/_uploads/SyOiSul60.png) 經過操作1 3 2 5後,畫布為 ![ShowImage (2)](https://hackmd.io/_uploads/HkzWLdeaC.png) ## 範測 ![螢幕擷取畫面 2024-09-12 220523](https://hackmd.io/_uploads/HJoEB_xaC.png) ![螢幕擷取畫面 2024-09-12 220553](https://hackmd.io/_uploads/Bk1IH_l60.png)