# 芝浦ばちゃ#9 (opens new window)
# A - 居合を終え、青い絵を覆う / UOIAUAI
# 概要
- 英小文字cがvowel(a/i/u/e/o)ならばvowel,そうでなければconsonantを出力せよ
# 提出コード
#include <bits/stdc++.h>
using namespace std;
int main(){
char c; cin>>c;
switch(c){
case 'a':
case 'i':
case 'u':
case 'e':
case 'o':
cout<<"vowel"<<endl;
break;
default:
cout<<"consonant"<<endl;
break;
}
return 0;
}
# B - Not Found
# 概要
- 文字列に含まれない英小文字のうち, 辞書式最小のものを出力せよ
- そのような英小文字が存在しない場合は,
None
を出力せよ
# 解法
- 26文字の英小文字(a〜z)について, 数え上げれば良い
- その後, 1回以上使われた文字の存在を確認すればよい
# 提出コード
#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
#define int int64
signed main() {
string s; cin>>s;
vector<int> cnt(26,0);
for(auto &&si: s){
++cnt[si-'a'];
}
for(int i=0;i<26;++i){
if(cnt[i]>0) continue;
// 文字コードで'a'からiだけずれている英小文字を出力
printf("%c\n", 'a'+i);
return 0;
}
cout<<"None"<<endl;
return 0;
}
# A - Shrinking
# 概要
- 英小文字からなる文字列が与えられる
- 次の操作をしてが単一の文字のみからなるようにする時の, 最小の操作回数を求めよ
- 長さの文字列を長さの文字列に変更する
- この時, の文字目は, の文字目のどちらかである
e.g.)
abcb
に1度の操作を加えるとbbb
にすることができるa
b
(abcb
のb
を1つずらして持ってきた(文字目を採用))b
b
(abcb
のb
をそのまま持ってきた(文字目を採用))c
b
(abcb
のb
を1つずらして持ってきた(文字目を採用))
# 解法
- 制約が
|s|≦100
とゆるゆるなので, 全探索したくなります(なります) - 全探索 とは, 具体的にa〜zの26文字全てで条件が満たせるかを 全 て 探索 することです
# 提出コード
#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
#define int int64
constexpr int INF = 1LL<<60;
signed main() {
string s; cin>>s;
vector<int> cnt(26,0);
for(int i=0;i<s.size();++i){
// 出現する文字数をカウント
++cnt[s[i]-'a'];
}
int ans = INF;
for(int i=0;i<26;++i){
// 出現しなかった文字はスルー
if(!cnt[i]) continue;
string cpy_s = s;
int cnt = 0;
// breakを含んでいるので, 兵庫県警には捕まりません
while(true){
// 全ての文字が同じ文字の時はbreak
if(string(cpy_s.size(), cpy_s[0])==cpy_s) break;
// i文字目かi+1文字目に'a'+iがあれば, それに変更(操作)
for(int j=0;j<cpy_s.size();++j){
if(cpy_s[j+1]=='a'+i || cpy_s[j]=='a'+i) cpy_s[j]='a'+i;
}
// 末尾を削除
cpy_s.pop_back();
++cnt;
}
ans = min(ans,cnt);
}
cout<<ans<<endl;
}
# C - 検索
# 概要
- 個の文字列が与えられる
- 文字列で 検索 すると, の中から先頭文字が一致している文字列が検索結果として得られる
- , , ..., 番目の文字列だけを検索結果として得たい時, そのような検索文字列が存在するか判定し, 存在する場合は長さが最小のものを求めよ
# 解法
editorial (opens new window)に沿って書いていく
検索ワードをとすると, 検索結果に出るか否かは次のように言い換えられる
- サイトが検索結果に出るとき, の先頭文字はである
e.g.)
- = "ab"の時, サイト = "abcde"が挙げられる
- この時, の先頭(=2)文字は, "ab"である
- サイトが検索結果に出ないとき, の先頭文字はでない
e.g.)
- = "ab"の時, サイト = "adcde"が挙げられる
- この時, の先頭(=2)文字は, "ab"ではない
- ここで, 検索に出したいサイトをとすると, 先ほどの条件を用いると以下のように言い換えられる
がを含む
- これは, 先ほどの考察により分かる
サイトを検索結果に出したいとき, との共通接頭辞がを含む
e.g.)
- = "ab"の時, = "abcd"が挙げられる
- ここで, を"abcc"とすると, との共通接頭辞は"abc"である
- 共通接頭辞"abc"は"ab"を含んでいるので, = "ab"の時にサイトは検索結果に表示される
- サイトを検索結果に出したくないとき, との共通接頭辞がを含まない
e.g.)
- = "ab"の時, = "abcd"が挙げられる
- ここで, を"accc"とすると, との共通接頭辞は"a"である
- 共通接頭辞"a"は"ab"を含んでいないので, = "ab"の時にサイトは検索結果に表示されない
- 以上の考察により, 以外のサイトについてとの共通接頭辞の長さをとする
e.g.)
- = "abcd, = "abbd"の時, 共通接頭辞は"ab"である
- したがって, = 2である
- すると, 条件はつぎのように言い換えられる
がを含む
- これは, 先ほどの考察で触れた
サイトを検索結果に出したいとき,
e.g.)
- = "ab", = "abcd"とする
- を検索結果に出したい時, としては"abc"や"ab", "abcdefg"などが挙げられる
- これらの文字列の特徴として, であることがわかる
- = "abc"の時,
- = "ab"の時,
- = "abcdefg"の時,
- サイトを検索結果に出したくないとき,
e.g.)
- = "ab", = "abcd"とする
- を検索結果に出したい時, としては"adc"や"a", "adcdefg"などが挙げられる
- これらの文字列の特徴として, であることがわかる
- = "adc"の時,
- = "a"の時,
- = "adcdefg"の時,
以上の考察より, 検索結果に出したいサイトのの最小値を,検索結果に出したくないサイトのの最大値をとすると, の条件は次のようになる
- がを含む
これを実装すればよい
# 提出コード
#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
#define int int64
signed main() {
int n,k;cin>>n>>k;
// 0で初期化
vector<int> a(n,0);
int r;
for(int i=0;i<k;++i) {
cin>>r;
// 表示したいものは1にする
a[--r] = 1;
}
vector<string> s(n);
for(int i=0;i<n;++i) cin>>s[i];
// S_rが含まれているもののうち, 最大のものを求める
string ans=s[r];
for(int i=0;i<n;++i) {
if(!a[i]) continue;
int cnt = 0;
for(int j=0;j<min(ans.size(), s[i].size());++j) {
if(ans[j]==s[i][j]) ++cnt;
else break;
}
// substrで再代入せずともresizeでおk
ans.resize(cnt);
}
// S_rが含まれていないもののうち, 最大のものを求める
int hide_max = -1;
for(int i=0;i<n;++i) {
if(a[i]) continue;
int cnt = 0;
// forループの条件より, hide_max < ans.size()が保証される
for(int j=0;j<min(ans.size(), s[i].size());++j) {
if(ans[j]==s[i][j]) ++cnt;
else break;
}
hide_max = max(hide_max, cnt);
}
// hide_max ==show_mnとなった時, 条件を満たさない
if(hide_max == ans.size()){
cout<<-1<<endl;
}else{
// hide_maxが1度も更新されずhide_max=-1の時は, substr(0,0), すなわち空文字が出力される
cout<<ans.substr(0,hide_max+1)<<endl;
}
return 0;
}
- お疲れ様でした