はっぴぃ☆わぁるど

思考垂れ流す肥溜め

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;
	}

}