[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
可以運用輾轉相除法呦!

## 範測
| 輸入 | 輸出 |
| ----- |:---- |
| 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後,畫布為

經過操作1 6 1 2後,畫布為

經過操作1 3 2 5後,畫布為

## 範測

