PKU演習問メモ(4/5 part2)
解説をだらだら書きすぎて(?)記事が長くなってしまったので分割。
No. | Title | 分類・解法 |
---|---|---|
1321 | 棋盘问题 | Counting up,DFS |
3749 | 破译密码 | String manipulation |
3751 | 时间日期格式转换 | String manipulation |
1951 | Extra Krunch | String manipulation |
以下問題概要や解説など。
1321 棋盘问题
問題概要
nxnマスのボードの#の印のついているマスに駒をk個置く。この時どの二つの駒も同じ列または行にないようにする。このような置き方の場合の数を求めよ。
解法
深さ優先探索で一行ずつ置き方を調べていって間に合う。
ソースコード
int n,k,ans; char bd[8][9]; bool use[8]; void rec(int c,int m) { if(m==k) { ans++; return; } if(c==n)return; rep(i,n)if(!use[i]&&bd[c][i]=='#') { use[i]=1; rec(c+1,m+1); use[i]=0; } rec(c+1,m); } int main() { while(cin>>n>>k,~n) { rep(i,n)cin>>bd[i]; ans=0; fill(use,use+n,0); rec(0,0); cout<<ans<<endl; } return 0; }
3749 破译密码
問題概要
シーザー式置換暗号の暗号文が与えられる。これを復号せよ。
解法
5つ前のアルファベットにずらす。
3751 时间日期格式转换
問題概要
yyyy/mm/dd-hh:mn:ssで表された日付時刻をmm/dd/yyyy-hh(0<h≦12):mn:ss(am|pm)の形式に変換せよ。
解法
無理矢理0を使わない所為で24時間形式で12:30は12時間形式の午後12:30に……
午前11:59→午後12:00→午後12:59→午後01:00ってなるの違和感ありすぎるw
パディングの0にも注意。(全然解法を説明していない)
ソースコード
int main() { int cs; cin>>cs; while(cs--) { string buf; cin>>buf; stringstream ss(buf.substr(11,2)); int h; ss>>h; bool am=1; if(h>=12)am=0; h%=12; if(h==0)h=12; cout<<buf.substr(5,5)<<"/"<<buf.substr(0,4)<<"-" <<(h<=9?"0":"")<<h<<buf.substr(13)<<(am?"am":"pm")<<endl; } return 0; }
一発ACだったんだから、勘違いしないでよね!
1951 Extra Krunch
問題概要
"krunched word"とは母音字が含まれず、かつ同じアルファベットが二度現れない文字列のことである。
一行で与えられた、アルファベット大文字、スペース、区切り文字からなる文字列を"krunched"に変換せよ。ただしスペースに関しては以下の規則を満たす必要がある。
- 行の最初と最後にスペースは現れない。
- 区切り文字の直前にスペースは現れない。
- スペースは連続しない。
解法
規則にしたがって実装する。区切り文字は複数あることに注意。
ソースコード
int main() { string str,ans; getline(cin,str); bool use[256]={0}; use['A']=use['E']=use['U']=use['I']=use['O']=1; fr(i,str) { if(*i==' ') { if(!ans.empty()&&*ans.rbegin()!=' ')ans.pb(*i); } else if(!('A'<=*i&&*i<='Z')) { if(!ans.empty()&&*ans.rbegin()==' ')*ans.rbegin()=*i; else ans.pb(*i); } else if(!use[*i]) { ans.pb(*i); use[*i]=1; } } while(!ans.empty()&&*ans.rbegin()==' ') { ans.erase(ans.end()-1,ans.end()); } cout<<ans<<endl; return 0; }