Codeforces #322 Div.2 C
今回は早めに4完して+4:-2Hackしたのでめちゃくちゃ得点が高い。やっぱり引っかかりやすいテストケースを用意してHackすると得点が高くなるなあという印象。
そして今回初めてDiv.1にあがることができた。1555->1741(+186)
問題はこちら Problem - C - Codeforces
kでシミュレーションすればいいかなと思ったが明らかに計算量が多い。貪欲に10-a%10が小さいものから順に能力を上げればいいとわかる。全部にあげ終わった後(ex: 10 20 40 20 10 10...)は、どれに10点ずつふりあてても変わらない。ただし得点の上限は10nであることに注意。
以上のことから、
① k < ならすまでに必要な能力値
貪欲に割り振る
②それ以外
ならしおわった後,得点の上限に気をつけるだけ
とやればいい。
以下ソースコード
int n,k,agel,point; int a[100010]; int main(){ cin.tie(0); ios::sync_with_stdio(false); cin>>n>>k; REP(i,n) cin>>a[i]; REP(i,n) agel += (a[i]%10==0 ? 0:10 - a[i]%10); if(agel <= k){ k -= agel; int asum=0; REP(i,n){ point += (a[i]+9)/10; a[i] += (a[i]%10==0 ? 0: 10 - a[i]%10 ); asum += 10 - a[i]/10; } if(asum <= k/10) point += asum; else point += k/10; //point += k/10; cout<<point<<endl; }else{ vector<pair<int,int> > p(n); REP(i,n) p[i] = mp((a[i]%10==0 ? 0:10 -a[i]%10), a[i]); sort(p.begin(),p.end()); int i=0; REP(i,n){ k -= p[i].first; if(k < 0) break; p[i].second += p[i].first; } REP(i,n) point += p[i].second/10; cout<<point<<endl; } }