DISCO presents ディスカバリーチャンネル プログラミングコンテスト2016 予選(A,B)
2完+部分点10点でした。
A - DISCO presents ディスカバリーチャンネルプログラミングコンテスト 2016
問題概要
"DiscoPresentsDiscoveryChannelProgrammingContest2016"という文字列を表示するが、1行にw文字までしか出力できない。w文字以降は折り返して表示される。どのように表示されるか。
解法
素直にシミュレーション。ループ回すだけなのでこれは出来ると思う。
#include <bits/stdc++.h> using namespace std; int main(){ string s="DiscoPresentsDiscoveryChannelProgrammingContest2016"; int w; cin>>w; int i=0; while(i<s.size()){ for(int j=0;j<w;j++){ if(i<s.size()){ cout<<s[i]; i++; } else break; } cout<<endl; } return 0; }
B - ディスコ社内ツアー
問題概要
ディスコ社内には部屋がn部屋、環状に並んでいる。部屋1から番号が増える順に並んでいて、ツアーでは部屋1から部屋の面白さが単調増加するように訪れ、部屋1で終わる。最低何周するか。
B: ディスコ社内ツアー - DISCO presents ディスカバリーチャンネル プログラミングコンテスト2016 予選 | AtCoder
解法
普通、部屋が近い順に訪れますよね…ということで最初にmapで部屋の面白さ毎にまとめ、後は頑張って処理。
#include <bits/stdc++.h> using namespace std; int main(){ int n; cin>>n; vector<int> a(n); for(int i=0;i<n;i++) cin>>a[i]; map<int,vector<int>> mp; for(int i=0;i<n;i++){ mp[a[i]].push_back(i); } int cnt=0,cur=0; for(auto it:mp){ auto v=it.second; auto next=lower_bound(v.begin(),v.end(),cur); if(distance(v.begin(),next)==0){ cur=v[v.size()-1]; } else{ cnt++; next--; cur=*next; } } if(0<cur){ cur=0; cnt++; } cout<<cnt<<endl; return 0; }
感想
B問題はもっと良い解法がありそう…
C,Dは全く歯が立たなかったです。Cに至っては部分点狙っても1ケースWAされる始末。(最初にaの文字列を読み飛ばして処理させたことが原因)
今日は昨日寝落ちして解けなかったyukiを解いて余裕があればこちらもやりたいです。