题目大意:给出n个塔的高度,每次只能移动塔顶的一个给另一个塔,求在k次范围内,最高塔与最低塔高度最小值的移动情况。
解题报告:做题的时候把题看错了,以为是每个塔之间的高度差,关键是用例居然还能推得过去。写了好久好多结果都错。今天才发现时最高和最低的高度,太伤心了,又掉分了。做法就是对塔高进行排序,然后K次循环将最高的给最低的,然后记录转移步骤,再次排序判断。只要高度差大于1则可以继续移动的,因此高度差小于等于1则跳出,否则要转移k次。注意对第一次进入的特判,详见code。
题目来源:http://codeforces.com/problemset/problem/479/B
code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1000+10;
int n,k,ans,tmp;
int st[MAXN][MAXN];
struct point{
int x,w;
}p[MAXN];
int cmp(point a,point b){
return a.w>b.w;
}
int main(){
//freopen("input.txt","r",stdin);
while(~scanf("%d%d",&n,&k)){
for(int i=0;i<n;++i){
scanf("%d",&p[i].w);
p[i].x=i+1;
}
sort(p,p+n,cmp);
ans=p[0].w-p[n-1].w;
int cnt=0;
while(k--){
if(ans==0) break;
p[0].w--;
p[n-1].w++;
st[cnt][0]=p[0].x;
st[cnt][1]=p[n-1].x;
sort(p,p+n,cmp);
tmp=p[0].w-p[n-1].w;
ans=tmp;
++cnt;
if(tmp<=1) break;
}
printf("%d %d\n",ans,cnt);
for(int i=0;i<cnt;++i)
printf("%d %d\n",st[i][0],st[i][1]);
}
return 0;
}