AtCoder Beginner Contest #009 C問題 - 辞書式順序ふたたび

Source

AtCoder Beginner Contest #009
問題文

問題概要

アルファベット小文字のみからなる $N$ 文字の文字列 $S$ が与えられる.
文字列 $S$ の置換 $T$ であって,$S$ と $T$ のハミング距離が $K$ 以下であるような $T$ のうち,辞書順で最小のものを求める問題.
$S$ と $T$ のハミング距離は,$k$ 文字目が違う文字になっているという $k$ の数.

解法

最初から決めつけていく辞書順最小のものを求めるテクニックを用いる.
最初から決めて行って,可能かどうかは,残りの部分をgreedyに割り当てれば良い.

C++によるスパゲッティなソースコード

#include<bits/stdc++.h>
using namespace std;

#define REP(i,a,b) for(i=a;i<b;i++)
#define rep(i,n) REP(i,0,n)

#define mygc(c) (c)=getchar_unlocked()
#define mypc(c) putchar_unlocked(c)

void reader(int *x){int k,m=0;*x=0;for(;;){mygc(k);if(k=='-'){m=1;break;}if('0'<=k&&k<='9'){*x=k-'0';break;}}for(;;){mygc(k);if(k<'0'||k>'9')break;*x=(*x)*10+k-'0';}if(m)(*x)=-(*x);}
void reader(int *x, int *y){reader(x);reader(y);}
int reader(char c[]){int i,s=0;for(;;){mygc(i);if(i!=' '&&i!='\n'&&i!='\r'&&i!='\t'&&i!=EOF) break;}c[s++]=i;for(;;){mygc(i);if(i==' '||i=='\n'||i=='\r'||i=='\t'||i==EOF) break;c[s++]=i;}return s;}
void writer(const char c[]){int i;for(i=0;c[i]!='\0';i++)mypc(c[i]);}

int N, K;
char in[1000], res[1000];
int rest[26];

int is_ok(void){
  int i, j, dame = 0;
  int now[26];

  rep(i,26) now[i] = rest[i];
  rep(i,N) if(res[i]!='*' && res[i]!=in[i]) dame++;
  rep(i,N) if(res[i]=='*'){
    if(now[in[i]-'a']) now[in[i]-'a']--;
    else               dame++;
  }

  if(dame > K) return 0;
  return 1;
}

int main(){
  int i, j;

  reader(&N,&K);
  reader(in);

  rep(i,N) res[i] = '*';
  res[N] = '\n';
  res[N+1] = '\0';

  rep(i,26) rest[i] = 0;
  rep(i,N) rest[in[i]-'a']++;

  rep(i,N){
    rep(j,26) if(rest[j]){
      rest[j]--;
      res[i] = 'a' + j;
      if(is_ok()) break;
      rest[j]++;
    }
  }

  writer(res);

  return 0;
}

Current time: 2017年07月21日13時31分44秒
Last modified: 2014年05月24日23時53分56秒 (by laycrs)
Tags: Competitive_Programming AtCoder AtCoder_Beginner_Contest ABC009 ABC_C
トップページに戻る

Logged in as: unknown user (not login)

ログイン: