# 🌟CPE一星題練習(上)
題目表來源:https://yuihuang.com/cpe-level-1-49/
下篇連結:https://hackmd.io/@herbert1018/HyrYO-P9Jl
刷了一點leetcode的easy跟medium後回來寫看看基礎一星題。
很多題都還可以寫得更好點,但要再研究,
阿程式架構的部分只是為了縮排才全塞一起。
# 📦1~5題
## 1. c039. 00100 – The 3n + 1 problem
直觀題,遞迴直接解,注意一下I跟J的大小關係。
```cpp=
#include<iostream>
#include<algorithm>
using namespace std;
int count(int n){
if(n==1)return 1;
if(n%2==1)return count(n*3+1)+1;
return count(n/2)+1;
}
int main(){
int i, j;
while(cin>>i>>j){
int ans=0;
cout<<i<<' '<<j<<' ';
if(i>j)swap(i, j);
for(int n=i; n<=j; n++){
ans=max(ans, count(n));
}
cout<<ans<<'\n';
}
return 0;
}
```
## 2. c082. 00118 – Mutant Flatworld Expolrers
來浪費時間的,我還在試著讓它變更短,
目前是直接用mod來維護方向、二維陣列控制前進座標、輸入輸出時用map轉換。
```cpp=
#include<iostream>
using namespace std;
int land[52][52]={0};
int dir[4][2]={{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
char dirMp[4]={'N', 'E', 'S', 'W'};
int main(){
char face;
string move;
int mx, my, nx, ny;//max, now;
cin>>mx>>my;
while(cin>>nx>>ny>>face>>move){
int flag=0, temp=104+(face=='E')+(face=='S')*2+(face=='W')*3;//mod
for(char c: move){
if(c=='F'){
int tx=nx+dir[temp%4][0], ty=ny+dir[temp%4][1];
if(tx>mx || ty>my || tx<0 || ty<0){
if(land[nx][ny])continue;
flag=land[nx][ny]=1;
break;
}
else{nx=tx; ny=ty;}
}
temp+=(c=='L')*-1+(c=='R');
}
cout<<nx<<' '<<ny<<' '<<dirMp[temp%4]<<((flag)?" LOST":"")<<'\n';
}
return 0;
}
```
## 3. c007. 00272 – TeX Quotes
用cin.get來讀取所有字元(包括空白及換行),用三元運算子跟and來精簡指令。
```cpp=
#include<iostream>
using namespace std;
int main(){
int temp=0;
char c;
while(cin.get(c)){
if(c=='"')cout<<((temp++&1)?"''":"``");
else cout<<c;
}
return 0;
}
```
## 4. e561. 00299 – Train Swapping
用最原始的bubble sort
```cpp=
#include<iostream>
using namespace std;
int main(){
int N, L=0;
cin>>N;
while(N--){
cin>>L;
int T[L], ans=0;
for(int i=0; i<L; i++)cin>>T[i];
for(int i=0; i<L; i++){
for(int j=0; j<L-i-1; j++){
if(T[j]>T[j+1]){
swap(T[j], T[j+1]);
ans++;
}
}
}
cout<<"Optimal train swapping takes "<<ans<<" swaps.\n";
}
return 0;
}
```
## 5. c045. 00490 – Rotating Sentences
這題zerojudge的測資有誤,下面解法送出後是對的,
只是很簡單的行列對調,不夠的地方補" "。
```cpp=
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
int main(){
int size=0;
string str;
vector<string> sen;
while(getline(cin, str)){
sen.push_back(str);
size=max(size, (int)str.length());
}
for(int i=0; i<size; i++){
for(int j=sen.size()-1; j>=0; j--){
if(i>=sen[j].size())cout<<" ";
else cout<<sen[j][i];
}
cout<<'\n';
}
return 0;
}
```
# 📦6~10題
## 6. a134. 00948 – Fibonaccimal Base
數字很小(最多只有38個),直接建表。
```cpp=
#include<iostream>
using namespace std;
int main(){
int fib[39]={1, 1};
for(int i=2; i<39; i++)fib[i]=fib[i-1]+fib[i-2];
int N, num;
cin>>N;
while(N--){
int flag=0;
cin>>num;
cout<<num<<" = ";
for(int i=38; i>0; i--){
if(num>=fib[i]){
flag=1;
cout<<1;
num-=fib[i];
}
else if(flag)cout<<0;
}
cout<<" (fib)\n";
}
return 0;
}
```
## 7. c044. 10008 – What’s Cryptanalysis
預先配置一個pair<char, int>做的vector,然後用lambda自訂排序
```cpp=
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
using pci=pair<char, int>;
int main(){
int n;
string str;
cin>>n;
cin.ignore();
vector<pci > mp;
for(char c='A'; c<='Z'; c++)mp.push_back({c, 0});
while(n--){
getline(cin, str);
for(char c:str){
if(isalpha(c)){
c=toupper(c);
mp[c-'A'].second++;
}
}
}
sort(mp.begin(), mp.end(), [&mp](pci x, pci y){
if(x.second!=y.second)return x.second>y.second;
else return x.first<y.first;
});
for(pci in: mp){
if(in.second==0)break;
cout<<in.first<<" "<<in.second<<'\n';
}
return 0;
}
```
## 8. e545. 10019 – Funny Encryption Method
__builtin_popcount可以回傳此數的2進裡有幾個1,阿16進就拆開看就好,
也可以寫一個簡單的function算,但我不要。
```cpp=
#include<iostream>
using namespace std;
int main(){
int T;
cin >> T;
while(T--){
int N, b1=0, b2=0;
cin >> N;
b1=__builtin_popcount(N);
while(N!=0){
b2+=__builtin_popcount(N%10);
N/=10;
}
cout<<b1<<' '<<b2<<'\n';
}
return 0;
}
```
## 9. c014. 10035 – Primary Arithmetic
注意最後面輸出的s
```cpp=
#include<iostream>
using namespace std;
int main(){
int x, y;
while(cin>>x>>y){
if(x==0 && y==0)break;
int ans=0, carry=0;
while(x!=0 || y!=0){
int a=x%10, b=y%10;
carry=(a+b+carry)/10;
if(carry)ans++;
x/=10; y/=10;
}
if(ans)cout<<ans;
else cout<<"No";
if(ans>=2)cout<<" carry operations.\n";
else cout<<" carry operation.\n";
}
return 0;
}
```
## 10. d097. 10038 – Jolly Jumpers
他是說要1到n-1每個都要有一個,不是說只要小於n就好。
```cpp=
#include<iostream>
#include<vector>
using namespace std;
int main(){
int n;
while(cin >> n){
int a, b;
vector<int> test(n, 0);
cin>>a;
for(int i=1; i<n; i++){
cin>>b;
test[abs(b-a)]++;
a=b;
}
bool flag=0;
for(int i=1; i<n; i++){
if(test[i]!=1){
flag=1;
break;
}
}
cout<<((flag)?"Not jolly":"Jolly")<<'\n';
}
return 0;
}
```
# 📦11~15題
## 11. a737. 10041 – Vito’s family
這題的問題是找中位數,而且沒有小數且偶數情況可以向下一數取整
所以就全用r/2。
```cpp=
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int n, r;
cin>>n;
while(n--){
cin>>r;
int h[r];
for(int i=0; i<r; i++)cin>>h[i];
sort(h, h+r);
int ans=0;
for(int i=0; i<r; i++)ans+=abs(h[i]-h[r/2]);
cout<<ans<<'\n';
}
return 0;
}
```
## 12. e579. 10050 – Hartals
bitset硬幹法
```cpp=
#include<iostream>
#include<bitset>
using namespace std;
int main(){
bitset<3652> day;
int T;
cin >> T;
while(T--){
day.reset();
int N, P, num;
cin >> N >> P;
while(P--){
cin >> num;
for(int i=1; i<=N/num; i++)day.set(num*i);
}
for(int i=0; i<N/7; i++){
day.reset(7*i+6);
day.reset(7*i+7);
}
cout << day.count()<<'\n';
}
return 0;
}
```
## 13. a012. 10055 – Hashmat the Brave Warrior
來搞笑的大數,用abs處理前後問題就好。
不過更大的話就得改用python,它作弊根本不在乎大數
```cpp=
#include<iostream>
using namespace std;
int main(){
long long a, b;
while(cin>>a>>b){
cout<<abs(b-a)<<'\n';
}
return 0;
}
```
## 14. e510. 10056 – What is the Probability?
題目敘述很繞,反正就是無窮等比級數求和,第一次用到iomanip
裡面的fixed(對齊小數:0.01->0.0100)、setprecision(看過沒用過)
```cpp=
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
int main(){
cin.tie(0);
int S;
cin>>S;
while(S--){
int N, i;
double p;
cin>>N>>p>>i;
if(p==0.0){
cout<<"0.000\n";
break;
}
cout<<fixed<<setprecision(4)
<<pow(1.0-p, i-1)*p/(1.0-pow(1-p, N))<<'\n';
}
return 0;
}
```
## 15. e606. 10057 – A mid-summer nights dream
阿不是跟前面第11題一樣,但這題測資很大不排除可能是暴力解
```cpp=
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n;
while (cin >> n){
int num[n];
for(int i=0; i<n; i++)cin>>num[i];
sort(num, num+n);
int mid1=num[(n-1)/2], mid2=num[n/2], ans=0;
for (int i=0; i<n; i++){
if (num[i]==mid1 || num[i]==mid2)ans++;
}
cout<<mid1<<" "<<ans<<" "<<mid2-mid1+1<<"\n";
}
return 0;
}
```
# 📦16~20題
## 16. c012. 10062 – Tell me the frequencies!
也是前面出現過的(第7題),只是變記ascii,然後可能會有空白行(換用getline)
突然發現也可以直接用傳統陣列放。
```cpp=
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
using pii=pair<int, int>;
int main() {
string str;
while (getline(cin, str)){
pii mp[256];
for(int i=0; i<256; i++)mp[i]={i, 0};
for(char i: str)mp[(int)i].second++;
sort(mp, mp+256, [&mp](pii x, pii y){
if(x.second!=y.second)return x.second<y.second;
else return x.first>y.first;
});
for(pii i: mp){
if(i.second==0)continue;
cout<<i.first<<" "<<i.second<<'\n';
}
cout<<'\n';
}
return 0;
}
```
## 17. d226. 10071 – Back to High School Physics
啊?
```cpp=
#include<iostream>
using namespace std;
int main() {
int v, t;
while(cin >> v >> t){
cout<<2*v*t<<'\n';
}
return 0;
}
```
## 18. UVA-10093 An Easy Problem!
zero judge版 n786. 10093 - An Easy Problem!
https://zerojudge.tw/ShowProblem?problemid=n786
OK解題就算了,題目還讓你看都看不懂
```cpp=
#include<iostream>
using namespace std;
int main() {
string str;
while(cin>>str){
int temp=0, sum=0, i=1;
for(char c: str){
if(c>='0' && c<='9')temp=c-'0';
else if(c>='A' && c<='Z')temp=c-'A'+10;
else if(c>='a' && c<='z')temp=c-'a'+36;
i=max(temp, i);
sum+=temp;
}
for(; i<62; i++){
if(sum%i==0){
cout<<i+1<<'\n';
break;
}
}
if(i==62)cout<<"such number is impossible!\n";
}
return 0;
}
```
## 19. a741. 10101 – Bangla Numbers
不管,暴力遞迴解
```cpp=
#include<iostream>
#include<iomanip>
using namespace std;
void bangla(long long x){
if(x>=10000000){
bangla(x/10000000);
cout<<" kuti";
x%=10000000;
}
if(x>=100000){
bangla(x/100000);
cout<<" lakh";
x%=100000;
}
if(x>=1000){
bangla(x/1000);
cout<<" hajar";
x%=1000;
}
if(x>=100){
bangla(x/100);
cout<<" shata";
x%=100;
}
if(x)cout<<" "<<x;
}
int main() {
long long n, t=1;
while(cin>>n){
cout<<setw(3)<<t++<<".";
if(n==0)cout<<0;
else bangla(n);
cout<<'\n';
}
return 0;
}
```
## 20. e555. 10170 – The Hotel with Infinite Rooms
算梯形面積,上底S是初始人數,下底Z是答案,然後不要超過面積D
(S+Z)x(Z-S+1)/2<=D -> ZxZ+Z<=2D+Sx(S-1)
阿你很閒還可以確認上下限後再寫一個二分搜,應該會快很多
```cpp=
#include<iostream>
using namespace std;
int main(){
long long S, D;
while(cin>>S>>D){
long long max=2*D+S*(S-1), Z=1;
while(Z*Z+Z<max)Z++;
cout<<Z<<'\n';
}
return 0;
}
```
# 📦21~25題
## 21. e605. 10189 - Minesweeper
直接開n+2乘m+2的int陣列,省去判斷的麻煩直接用雙迴圈++。
```cpp=
#include<iostream>
using namespace std;
int main(){
int F=1, n=0, m=0;
while(cin>>n>>m){
if(!(n||m))return 0;
int map[n+2][m+2]={0};
bool posion[n+2][m+2]={0};
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
char c;
cin>>c;
if(c=='*'){
posion[i+1][j+1]++;
for(int k=0; k<3; k++){
for(int l=0; l<3; l++){
map[k+i][l+j]++;
}
}
}
}
}
cout<<"Field #"<<F++<<":\n";
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
if(!posion[i][j])cout<<map[i][j];
else cout<<'*';
}
cout<<'\n';
}
}
return 0;
}
```
## 22. e566. 10190 - Divide, But Not Quite Conquer!
也可以直接用vector寫,但我寫過了想試試看用遞迴寫
```cpp=
#include<iostream>
using namespace std;
bool boring(int n, int &m){
if(n==1)return false;
if(n%m!=0)return true;
return boring(n/m, m);
}
int main(){
int n, m;
while(cin>>n>>m){
if(n==0||m==0||boring(n, m))cout<<"Boring!\n";
else{
while(n>0){
cout<<n<<' ';
n/=m;
}
cout<<'\n';
}
}
return 0;
}
```
## 23. d306. 10193 - All You Need Is Love
先轉成int在找最大公因數(gcd)。有一說一,此輾轉相除寫法不適用0的情形
```cpp=
#include <iostream>
#include <string>
using namespace std;
int gcd(int x, int y){
while ((x %= y) && (y %= x));
return x + y;
}
int s2n(string &str){
int n=0;
for (int i = 0; i < str.size(); i++){
n *= 10;
n += str[i] - '0';
}
return n;
}
int main() {
int N;
string S1, S2;
cin >> N;
for (int Case = 1; Case <= N; Case++){
cin >> S1 >> S2;
int n1 = s2n(S1), n2 = s2n(S2);
cout << "Pair #" << Case;
if (gcd(n1, n2) > 1) cout << ": All you need is love!\n";
else cout << ": Love is not all you need!\n";
}
return 0;
}
```
## 24. UVA-10221 Satellites
WTF,直接看題解的,根本不知道是三小
```cpp=
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
#define PI acos(-1)
int main() {
double s, a, r=6440;
string str;
while(cin>>s>>a>>str){
if(str=="min")a/=60;
if(a>180)a=360-a;
double chord=(r+s)*sin(a*PI/360)*2;
double arc=2*PI*(r+s)*a/360;
cout<<fixed<<setprecision(6)<<arc<<" "<<chord<<'\n';
}
return 0;
}
```
## 25. e578. 10222 - Decode the Mad man
硬幹法
```cpp=
#include<iostream>
#include<string>
using namespace std;
int main(){
string s="`1234567890-=qwertyuiop[]\\asdfghjkl;'zxcvbnm,./";
string str;
while(getline(cin, str)){
for(char c: str){
if(c==' ')cout<<" ";
else if(c=='`'|| c=='1'|| c=='q'|| c=='w'||
c=='a'|| c=='s'|| c=='z'|| c=='x')break;
else{
int it=s.find(c);
cout<<s[it-2];
}
}cout<<'\n';
}
return 0;
}
```