Codeforces 1255D Feeding Chicken

思路:

1.题意是给每只鸡分配一块地方,地方必须连续,所有鸡分配完地方,它们拥有的粮食肯定有差异,我们要做的就是使拥有最多粮食的鸡拥有的粮食和拥有最少粮食的鸡拥有的粮食之差最小;
2.利用贪心思想,设粮食总数是ans,则我们可以将这个差值减小到1或0,令a=ans/k,k=a+1,则此时有m只鸡拥有a块粮食,n只鸡拥有b块粮食,此时|a-b|=1,而mn满足
{m+n=kam+bn=ans \begin{cases} m+n=k\\ am+bn=ans \end{cases}
m、n解出,然后依次沿S形遍历农场(来保证每只鸡土地连续),依次给每只鸡分配土地即可~;
土地编号可以提前定义在数组里;

代码:

#include<bits/stdc++.h>
using namespace std;
#define rp(i,n) for(int i=0;i<n;i++)
#define rpn(i,n) for(int i=1;i<=n;i++)
const int MAX_N=105; 
const int MAX_K=62;
char label[MAX_K];
char farm[MAX_N][MAX_N];
void init(){
	int pos=0;
	rp(i,10) label[pos++]=i+'0';
	rp(i,26) label[pos++]=i+'a';
	rp(i,26) label[pos++]=i+'A';
}
int r,c;
void next(int& x,int& y){
	if(x&1){
		if(y>0) y--;
		else x++;
	}else{
		if(y<c-1) y++;
		else x++;
	}
}
int main(){
	init();
	int t;
	scanf("%d",&t);
	while(t--){
		int k,ans=0;
		scanf("%d%d%d",&r,&c,&k);
		rp(i,r){
			getchar();
			rp(j,c){
				farm[i][j]=getchar();
				if(farm[i][j]=='R') ans++;
			}
		}
		int a=ans/k,b=a+1;
		int n=(ans-a*k)/(b-a),m=k-n;
		int pos=0,x=0,y=0,cnt=0;
		while(m--){
			while(true){
				if(farm[x][y]=='R') cnt++;
				farm[x][y]=label[pos];
				next(x,y);
				if(cnt==a){pos++;cnt=0;break;}
			}
		}
		while(n--){
			while(true){
				if(farm[x][y]=='R') cnt++;
				farm[x][y]=label[pos];
				next(x,y);
				if(cnt==b){pos++;cnt=0;break;}
			}
		}
		pos--;
		rp(i,r){
			rp(j,c){
				if(farm[i][j]!='.') putchar(farm[i][j]);
				else putchar(label[pos]);
			}
			putchar('\n');
		}
	}
	return 0;
}
posted @ 2019-11-23 20:31  YuhanのBlog  阅读(115)  评论(0编辑  收藏  举报