###### tags: `ZERO JUDGE` `C` `A series` # 資工三乙 許皓翔 # A :::spoiler <font size=4>**a006: 一元二次方程式**</font> ``` c= # include <stdio.h> # include <math.h> int main(void) { int a, b, c; scanf("%d %d %d", &a, &b, &c); int z = (b * b) - (4 * a * c); int r1 = (-b + sqrt(z)) / (2 * a); int r2 = (-b - sqrt(z)) / (2 * a); if(z > 0) printf("Two different roots x1=%d , x2=%d\n", r1, r2); else if(z == 0) printf("Two same roots x=%d\n", -b / (2 * a)); else printf("No real root\n"); } ``` :::warning <font size=5>**解題思路**</font> 國中教過的公式解 $\Rightarrow x = \dfrac{-b \pm \sqrt{b^{2}-4ac}}{2a}$ 判別式 $D = \sqrt{b^{2}-4ac}$ 再用判別式的大小來判斷是否存在根(root) and 兩根為多少 **2023/1/17** ::: :::spoiler <font size=4>**a009: 解碼器**</font> ```c= # include <stdio.h> # include <string.h> int main(void) { char ip[1000]; gets(ip); for(int i = 0; i < strlen(ip); i++) printf("%c", ip[i] - 7); } ``` :::warning <font size=5>**解題思路**</font> 用題目的 **密碼** 來判斷金鑰K為多少(K = 7) 再反推回去 **明碼** **2023/1/19** ::: :::spoiler <font size=4>**a013 羅馬數字**</font> 主函式部分: ```c= # include <stdio.h> # include <string.h> int romanToInt(char str[]); int getValue(char); void intToRoman(int); int abs(int); int main(void) { char str1[100]; char str2[100]; int a, b;// a 為被減數 b 為減數 while(scanf("%s", str1)) { if(str1[0] == '#') break; scanf("%s", str2); a = romanToInt(str1); b = romanToInt(str2); if(abs(a - b) == 0) printf("ZERO\n"); else intToRoman(abs(a - b)); } } ``` 羅馬數字轉阿拉伯數字: ```c=+ int romanToInt(char str[]) { int z, sum = 0; for(int i = 0; i < strlen(str); i++) { z = getValue(str[i]); if(i == strlen(str) - 1) { sum += z; break; } else if(z < getValue(str[i + 1])) sum -= z; else sum += z; } return sum; } ``` 讓每個羅馬字查詢自己對應的阿拉伯數字之函數: ```c=+ int getValue(char ch) { char str[] = "MDCLXVI"; int num[] = {1000, 500, 100, 50, 10, 5, 1}; for(int i = 0; i < strlen(str); i++) { if(ch == str[i]) return num[i]; } } ``` 阿拉伯數字轉羅馬數字: ```c=+ void intToRoman(int x) { char str[][3] = {"I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"}; int num[] = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000}; int n = 12; int z; // z 為餘數 while(n > 0) { int d; // d 為商 if(num[n] <= x) { z = x % num[n]; d = x / num[n]; if(d > 1) { for(int i = 0; i < d; i++) printf("%s", str[n]); } else printf("%s", str[n]); x = z; } n --; } for(int i = 0; i < x; i++) printf("%c", 'I'); printf("%c", '\n'); } ``` 絕對值函數: ```c=+ int abs(int x) { if(x < 0) return -x; else return x; } ``` :::warning <font size=5>**解題思路**</font> ``intToRoman():`` 1. 建立一個由小->大排序的除數陣列 num (其實大->小也行, 只要讓 n 初值=0) 再建立一個與其對應的羅馬數字的字串陣列 str 2. 遍歷 num 中的所有元素並讓 被除數x 與其進行運算(與 x 相除取餘數z), 並且只有除數比被除數小的才可以進行運算 3. 變數 d 用來紀錄運算後的商 以除數=num[4] (對應到str[4]="x")為例, 若運算後 d = 3 代表 "x" 有三個(就要printf()三次) ``romanToInt()`` // 想法源自leetcode 13. Roman to Integer 對於傳入的羅馬字串中若當前那個字元所對應的阿拉伯數字(利用getValue()查詢)小於下一個字元的,視為特殊情況, 若當前字元之阿拉伯數字為1, 下一個字元為5, 就把 1 視為 -1(因為羅馬人規定IV=4 故可推斷IV為-1+5計算而來), 因為在對羅馬數字進行其阿拉伯數值轉換計算時的 sum值 不一定都全為往上加(特殊情況時會減) **2023/1/21** ::: :::spoiler <font size=4>**a044 空間切割**</font> ```c= # include <stdio.h> int main(void) { int n; while(scanf("%d", &n) != EOF) printf("%d\n", (power(n, 3) + (5 * n) + 6) / 6); } int power(int x, int n) { if(n == 0) return 1; else return x * power(x, n - 1); } ``` :::warning <font size=5>**解題思路**</font> 空間中 n 個平面切割空間的公式 $Sn = \dfrac{n^{3}+5n+6}{6}$ **2023/1/22** :::