HP CodeWars 2007 參考解答
************ 1. Powers of Two ************
//1. Powers of Two (HP CodeWars 2007) by Snail
#include <iostream>
using namespace std;
int main () {
int n, i;
cin >> n;
for (i=0; i<=n; i++)
cout << "2^" << i << " = " << (1 << i) << endl;
}
************ 2. Vertical Printing ************
//2. Vertical Printing (HP CodeWars 2007) by Snail
#include <iostream>
#include <string>
using namespace std;
int main () {
string s[17];
int n=0, i, j, mxl=0;
while (getline(cin,s[n]), s[n]!="END")
mxl = max ((int)s[n++].size(), mxl); //mxl--字串最大長度
for (i=0; i<n; i++)
s[i] += string (mxl-s[i].size(), ' '); //補空白
for (j=0; j<mxl; j++) {
for (i=0; i<n; i++)
cout << s[i][j] << " ";
cout << endl;
}
}
************ 3. Combination ************
//3. Combination (HP CodeWars 2007) by Snail
#include <iostream>
using namespace std;
int main () {
int n, m, c, i; //c(ombination)--組合
while (cin >> n >> m) {
m = min (m, n-m); //c(n,m) == c(n,n-m)
c = 1;
for (i=1; i<=m; i++)
c = c * (n-i+1) / i;
cout << c << endl;
}
}
************ 4. Password Analyzer ************
//4. Password Analyzer (HP CodeWars 2007) by Snail
#include <iostream>
#include <string>
using namespace std;
int main () {
string s, strength[] = {"WEAK", "ACCEPTABLE", "GOOD", "STRONG"};
while (cin >> s) {
int uc=0, lc=0, ds=0, i;
for (i=0; i!=s.size(); i++) {
uc = uc || isupper(s[i]); //u(pper) c(ase)--大寫
lc = lc || islower(s[i]); //l(ower) c(ase)--小寫
ds = ds || isdigit(s[i]) //d(igit) or s(ymbol)
|| ispunct(s[i]); //--數字或符號
}
i = (s.size()>=8) + (uc && lc) + ((uc || lc) && ds);
cout << "This password is " << strength[i] << endl;
}
}
************ 5. Overhanging Cards ************
//5. Overhanging Cards (HP CodeWars 2007) by Snail
#include <iostream>
using namespace std;
int main () {
float c, s, n; //有處理浮點數誤差的話,float 也能 AC
while (cin >> c) {
s = 0;
for (n=2; s+1e-6<c; n++) //1e-6 : 浮點數誤差
s += 1 / n;
cout << n-2 << " card(s)\n";
}
}
************ 6. Prime Directive ************
//6. Prime Directive (HP CodeWars 2007 (by Snail)
#include <iostream>
#include <iomanip>
using namespace std;
int main () {
int n, i, k=2, np=0, p[1010]={};
while (k < 1000) {
while (p[k]) //找下一個質數 k
k++;
p[np++] = k; //記錄質數
for (i=k; i<=1009; i+=k) //篩掉 k 的倍數
p[i] = 1;
}
while (cin >> n) {
for (i=0; p[i] <= n; i++) { //列出 <= n 的質數
if (i && i%5 == 0) //已輸出 5 個質數
cout << endl; // 換行
cout << setw(10) << p[i];
}
cout << endl;
}
}
************ 7. RAID Sizer ************
//7. RAID Sizer (HP CodeWars 2007) by Snail
#include <iostream>
using namespace std;
int main () {
int r, i, c, q, t, ac, mini, mint, minq, minc;
int dc[4] = {250,400,500,750}, dp[4] = {75,110,140,250};
while (cin >> c >> r) { //c(apacity)--容量
mint = 2001;
for (i=0; i<4; i++) {
q = (c-1) / dc[i] + 1; //硬碟數量無條件進位
ac = dc[i] * q; //陣列實際容量
if (r == 1)
q *= 2; //RAID 1 需要 2 倍硬碟
else if (r)
q += 1; //RAID 5 需要多 1 顆硬碟
if (q <= 8) { //最多 8 顆硬碟
t = q * dp[i]; //總金額
if (t < mint)
mint = t, minq = q, mini = i, minc = ac;
}
}
cout << "Qty: " << minq << " Disk: " << dc[mini] << "GB Price: $" << dp[mini] << endl;
cout << "Total price of this " << minc << "GB array: $" << mint << endl;
}
}
************ 8. Number Spiral ************
//8. Number Spiral (HP CodeWars 2007) by Snail
#include <iostream>
#include <iomanip>
using namespace std;
int main () {
int n, m[19][19], sn=0, x, y, k;
x = 8, y = 9;
for (k=0; k<=9; k++) {
x++, y++; //向右移出
while (y > 9-k) //向上
m[--y][x] = sn++;
while (x > 9-k) //向左
m[y][--x] = sn++;
while (y < 9+k) //向下
m[++y][x] = sn++;
while (x < 9+k) //向右
m[y][++x] = sn++;
}
while (cin >> n) {
n /= 2;
for (y=9-n; y<=9+n; y++){ //輸出陣列
for (x=9-n; x<=9+n; x++)
cout << setw(4) << m[y][x];
cout << endl;
}
cout << endl;
}
}
************ 9. Musical Intervals ************
//9. Musical Intervals (HP CodeWars 2007) by Snail
#include <iostream>
#include <string>
using namespace std;
int main () { //n(ote) n(name)--音名
string nn[12] = {"C","C#","D","D#","E","F","F#","G","G#","A","A#","B"};
int n, i, k, sc[7] = {0,2,4,5,7,9,11}; //sc(ale)--大調音階
char ch;
while (cin >> ch) {
k = sc[(ch-'A'+5)%7]; //k(ey)--調名
if (cin.peek() == '#') //升半音
k++, cin.ignore();
cout << nn[k]; //輸出起始主音
n = 0;
while (cin.peek() != '\n') {
cin >> i; //輸入音程
i += (i<0) - (i>0); //扣掉起始音本身
n = (n + i + 49) % 7; //計算下一個音符
cout << ' ' << nn[(k+sc[n])%12]; //輸出音名
}
cout << endl;
}
}
************ 10. New Math ************
//10. New Math (HP CodeWars 2007) by Snail
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int main () {
long long s, t;
int a, b;
string n, d = "0123456789abcdefghij";
char ch;
while (cin >> ws, !cin.eof()) {
getline (cin, n, '^');
cin >> b; //b(ase)--底
t = strtol (n.c_str(), NULL, b); //將字串 n 轉成 int
s = 0, ch = ' ';
while (ch != '=') { //處理 = 後跳出
cin >> ch; //運算子
getline (cin, n, '^'); //運算元
cin >> b; //底
a = strtol (n.c_str(), NULL, b);
if (ch == '*')
t *= a; //t(erm)--乘積
else {
s += t, t = a; //s(um)--和
if (ch == '-')
t = -t;
}
}
if (s < 0)
cout << '-', s = -s; //去掉負號
while (s) { //轉成 b 進位
n = d[s%b] + n;
s /= b;
}
cout << n << '^' << b << endl;
}
}
************ 11. LED Decoder ************
//11. LED Decoder (HP CodeWars 2007) by Snail
#include <iostream>
#include <string>
using namespace std;
int main () {
string s, a = "BAROWQMESGHKUZFYVPDJNLTCIX ";
string c[27] = {"1234567","123457","123459","123567","135790","12347","12357","12456","12467","12569","13457","13459",
"13567","23456","1249","1347","1379","1458","1580","3567","3579","156","278","456","37","90","0"};
int i, p;
while (getline(cin,s)) {
for (i=0; i<27; i++) {
p = -1;
while ((p=s.find(c[i],p+1)) != -1) //把 s 中所有的 c[i]
s.replace(p,c[i].size(),1,a[i]);//換成 a[i];
}
cout << s << endl;
}
}
************ 12. Domino Rally ************
//12. Domino Rally (HP CodeWars 2007) by Snail
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;
int main () {
int n, i, f;
int d[29][2] = {{},{0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{1,1},{1,2},
{1,3},{1,4},{1,5},{1,6},{2,2},{2,3},{2,4},{2,5},{2,6},{3,3},
{3,4},{3,5},{3,6},{4,4},{4,5},{4,6},{5,5},{5,6},{6,6}};
char o; //o(rietation)--方向
while (cin >> n >> o) {
vector <int> r; //r(ally)
do {
if (o == 'B') n = -n; //若反向則加負號
r.push_back(n); //將點數加入陣列 r
} while (cin >> n >> o, n); //輸入下一張骨牌
do {
f = false; //f(ound)--找到相同點數
for (i=0; i+1<(int)r.size(); i++)
if (d[abs(r[ i ])][r[ i ]>0] == //這張骨牌右側點數
d[abs(r[i+1])][r[i+1]<0]) { //與下一張左側點數相同
r.erase (r.begin()+i, r.begin()+i+2);
f = true; //移除兩張骨牌
break;
}
} while (f); //若有相同點數重頭開始
if (r.size()) {
for (i=0; i!=r.size(); i++)
cout << abs(r[i]) << ' '; //輸出 n
cout << endl;
} else
cout << "DATASET CLEARED\n";
}
}
************ 13. Not Quite OCR ************
//13. Not Quite OCR (HP CodeWars 2007) by Snail
#include <iostream>
#include <string>
using namespace std;
int main () {
string dm[10] = {" _ | ||_|"," | |"," _ _||_ "," _ _| _|"," |_| |",
" _ |_ _|"," _ |_ |_|"," _ | |"," _ |_||_|"," _ |_| _|"};
char ch;
int n, i, j, cs, g, d[10];
cin >> n;
while (n--) {
string m[10]; //m[i]--第i位掃瞄影像
for (i=0; i<3; i++) {
cin.ignore(99,'\n'); //跳過換行
for (j=0; j<27; j++) {
cin.get(ch); //輸入影像
m[9-j/3] += ch; //接到適當的位數
}
}
cs = g = 0;
for (i=1; i<=9; i++) {
for (j=0; j<=9 && m[i]!=dm[j]; j++);//比對數字影像
if (j > 9) //若比對失敗
g = i; //g(arble)--模糊
else
d[i] = j, cs += i * j; //計算檢查碼
}
if (g)
for (d[g]=0; d[g]<=9; d[g]++) //還原模糊的數字
if ((cs + d[g]*g) % 11 == 0)
break;
if (g && d[g]>9 || !g && cs%11!=0) //無法還原或檢查碼錯誤
cout << "failure\n";
else {
for (i=9; i; i--)
cout << d[i];
cout << endl;
}
}
}
************ 14. Knights Path ************
//14. Knights Path (HP CodeWars 2007) by Snail
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
vector <string> nxt[8][8]; //下一步的位置
void trace (int x, int y, string s) {
if (nxt[x][y].size()) { //若有下一步
sort (nxt[x][y].begin(), nxt[x][y].end());//依字典順序排序
for (int i=0; i!=nxt[x][y].size(); i++) {
string p = nxt[x][y][i];
trace (p[0]-'a',p[1]-'1',s+" "+p); //遞迴到下一步
}
} else //到達終點時
cout << "Solution: " << s << endl; //輸出解答
}
int main () {
int qf, qb, x, y, x1, y1, i, j, bd[8][8]; //bd (board)--棋盤
int dx[8] = {-2,-2,-1,-1, 1, 1, 2, 2}; //d(elta) x--X 座標差
int dy[8] = {-1, 1,-2, 2,-2, 2,-1, 1}; //d(elta) y--Y 座標差
string s, e, b, p, q[64];
while (cin >> s >> e) { //s(tart)--起點, e(nd)--終點
for (i=0; i<8; i++)
for (j=0; j<8; j++) //9999--未到過
bd[i][j] = 9999, nxt[i][j].clear();
while (cin >> b, b != "xx") //b(locker)--路障
bd[b[0]-'a'][b[1]-'1'] = -1; //記錄路障
bd[e[0]-'a'][e[1]-'1'] = 0; //從終點往回找
qf = qb = 0; //q(ueue) f(ront)--頭, b(ack)--尾
q[qb++] = e; //將終點推入佇列
while (q[qf] != s) { //尚末找到起點時
p = q[qf++]; //從佇列取出一點
x = p[0]-'a', y = p[1]-'1';
for (i=0; i<8; i++) { //能走的 8 個方向
x1 = x + dx[i];
y1 = y + dy[i];
if (x1<0 || x1>7 || y1<0 || y1>7//超出範圍
|| bd[x1][y1] < bd[x][y] + 1)//或已有更小步數
continue; //跳過
if (bd[x1][y1] == 9999) { //若未拜訪過
bd[x1][y1] = bd[x][y] + 1; //步數 +1
q[qb ] = char(x1+'a'); //推入佇列
q[qb++] += char(y1+'1');
}
nxt[x1][y1].push_back(p); //記錄下一步位置
}
}
cout << "The shortest solution is " << bd[s[0]-'a'][s[1]-'1'] << " move(s).\n";
trace (s[0]-'a',s[1]-'1',s); //從起點往下遞迴
}
}