ABC009に参加。Aを1s差でFAを逃してしまった。
Dに若干苦戦したが何とか正答。
すいません、DだけPythonでTLEしたためC++です。
http://abc009.contest.atcoder.jp/assignments
A - 引越し作業
段ボールがN個ある。1回で2個ずつ運べるとき、全段ボールを運ぶのに何回かかるか。
(N+1)/2で良い。
import sys N=input() M={} print (N+1)/2
B - 心配性な富豪、ファミリーレストランに行く。
N個のメニューの価格が与えられる。
2番目に高い価格を答えよ。
一旦全部setに放り込んで重複をなくした上、ソートして後ろから2つ目を答えればよい。
import sys N=input() S=set() for i in range(0,N): S.add(input()) L=list(S) L.sort() print L[-2]
C - 辞書式順序ふたたび
文字列Sが与えられる。
このうち最大K文字まで位置を入れ替えて作れる文字のうち、辞書順最小のものを求めよ。
ヒントに従い答えの文字列の先頭から決めていく。
候補として'a'~'z'まで入れてみて、「その値を入れても残りの文字が(K-1)文字の入れ替えで済む」ならその文字を採用していく。
うーん、これ系の問題(一発で最適解を求める必要はなく、条件をはみ出ない範囲で解を絞り込んでいく)は苦手だ…。ヒントなしだと解けてないなこれ。
import sys N,K=map(int,raw_input().strip().split(" ")) S=raw_input().strip() C={} def okok(ind,num): C2 = C.copy() for i in range(ind,N): if C2[S[i]] > 0: C2[S[i]] -= 1 else: num -= 1 return num >= 0 for c in range(ord('a'),ord('z')+1): C[chr(c)] = 0 for c in S: C[c] += 1 T='' for i in range(0,N): for j in range(ord('a'),ord('z')+1): c=chr(j) if C[c] > 0: C[c] -= 1 if S[i]!=c: K -= 1 if okok(i+1,K): T += c break if S[i]!=c: K += 1 C[c] += 1 print T
D - 漸化式
数列A,Cのうち先頭K個が与えられる。
K+1要素目以降は、A[N+K] = (C[1]&A[N+K-1]) ^ (C[2]&A[N+K-2]) ^ ... ^ (C[K]&A[N+K-K])で生成される。
A[M]を求めよ。
最初周期性があるかと考えて、周期性が出るまで試したが、最長で2^Kの周期になるため失敗した。
ここではK+1項間漸化式を行列で表現し、その行列のM乗を求めることで対応した。
なお、行列のM乗において、+と*の代わりにxorとandを使う必要がある。
また、単位行列の代わりに2^32-1を用いる必要がある。
以下の解法は、O(K^3*logM)である。PythonだとTLEしてしまったので、C++の回答のみ掲載。
const int MAT=101; ll G[MAT][MAT],G2[MAT][MAT]; void powmat(ll p,ll n,ll a[MAT][MAT],ll r[MAT][MAT]) { ll i,x,y,z; ll a2[MAT][MAT]; FOR(x,n) FOR(y,n) a2[x][y]=a[x][y]; FOR(x,n) FOR(y,n) r[x][y]=0; FOR(i,n) r[i][i]=(1LL<<32)-1; while(p) { ll h[MAT][MAT]; if(p%2) { FOR(x,n) FOR(y,n) { h[x][y]=0; FOR(z,n) h[x][y] ^= r[x][z]&a2[z][y]; } FOR(x,n) FOR(y,n) r[x][y]=h[x][y]; } FOR(x,n) FOR(y,n) { h[x][y]=0; FOR(z,n) h[x][y] ^= a2[x][z]&a2[z][y]; } FOR(x,n) FOR(y,n) a2[x][y]=h[x][y]; p>>=1; } } ll A[101],C[101]; ll K,M; int loop[32]; void solve() { int f,i,j,k,l,x,y; cin>>K>>M; M--; FOR(i,K) cin>>A[i]; FOR(i,K) cin>>C[i]; //if(M<K) return _P("%lld\n",A[M]); ll ret=0; ZERO(G); FOR(j,K-1) G[j+1][j]=(1LL<<32)-1; FOR(j,K) G[0][j]=C[j]; powmat(M,K,G,G2); FOR(j,K) ret^=A[j] & G2[K-1][K-1-j]; cout << ret << endl; }
まとめ
DはPythonでライブラリ無しでTLEせず解けるの…?