uva Diatribe against Pigeonholes (模拟 但是被分在DP的类别中)

这是一道关于模拟分配任务的问题,目的是保护脆弱的中间鸽巢。输入包含多个测试用例,每个用例给出公司工人数量(1 < N < 26)和对应工人的字母,字母表示包裹。任务是将最重的包裹放在远离中间鸽巢的位置。输出是按顺序排列的工人字母和各鸽巢的包裹数量,如果有多个解,则输出字母顺序靠前的那个。
摘要由CSDN通过智能技术生成
 Diatribe against Pigeonholes 

Background

In an anonymous town there is a carpenter, the only one in many kilometres,specialized in making pieces of furniture (and famous for being a bit stingywith the screws). This carpenter made a shelving for a company, using only twoscrews.

The Problem

We have a lineal set of N similar pigeonholes (numbered1, 2, 3, ..., N, with 1< N < 26) forming ashelving, where N workers of a company receive their mail.Each worker has an associated capital letter,A, B,C, and so on, until Z if necessary. Your task is toassociate each worker with one pigeonhole. As the shelving isfragile in the middle  (i.e., pigeonhole (N+1)/2) due to thestinginess of the carpenter, wehave to put the mail of each worker as follows: the heaviestones, the further from the middle of the shelving, in order to protect theshelving. You mustsuppose that all parcels weigh the same weight.

TheInput

The first line of the input contains an integer, M,indicating the number of test cases. For each test case, thefirst line indicates the numberN of workers (andpigeonholes) of the company, 1 < N < 26. One moreline follows, containing a string of capital letters,corresponding each one with a parcel destinated to thecorresponding worker, finished with a “#” character.For example, the string ABABBAA# means that worker A receives 4 parcels, and B receives 3. Characters not corresponding withvalid workers must be omitted.

TheOutput

For each test case, the output should consist of two lines,the first one showing the secuence of workers corresponding withthe obtained ordering, separated with one blank space. If thereis more than one solution, you have to output the alphabetically first. The second line will consist of the number of parcels ineach pigeonhole, in the same order of the previous line, and alsoseparated with one blank space.

SampleInput

4
5
BDCECDCBCBCDECDABCEDVBCDBCDBCDABCAED#
7
BGFADCEDGFCDEGCFCGDGCXXDAEDACEACEGFAGFCEDGCEDGBCD#
24
AABACDEDFGHMMJNTBNHGTDFACCDLLPPPERRAMMMMKKKKJJJHHHAAAAGGGQQQLLLLPPPAA#
10
PDJFGEDFANGEHIAEJBHJGEDGJGJEINDFJHEIEDGHFFGHDHGFHAJGIE#

SampleOutput

C B A E D
11 8 3 4 9
C D A B F E G
10 9 5 2 5 7 9
A L G D C B E F I O S U V W X N R T Q J K H M P
11 6 5 4 3 2 2 2 0 0 0 0 0 0 0 2 2 2 3 4 4 5 6 6
E H D A B C I F J G
8 7 6 3 1 0 4 6 7 9


#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

const int maxn = 30;
struct parcel{
	int letter;
	int total;
	parcel(int a = 0 , int b = 0){
		letter = a , total = b;
	}
};
int ans[maxn] , sum[maxn] , N;
vector<parcel> p;

bool cmp(parcel p1 , parcel p2){
	if(p1.total == p2.total){
		return p1.letter<p2.letter;
	}
	return p1.total>p2.total;
}

void initial(){
	for(int i = 0;i < maxn;i++){
		ans[i] = 0;
		sum[i] = 0;
	}
	p.clear();
}

void readcase(){
	scanf("%d" , &N);
	string str;
	while(cin >> str){
		for(int i = 0;i < str.length();i++){
			if(str[i]-'A' >= 0 && str[i]-'A' < N){
				sum[str[i]-'A']++;
			}
		}
		if(str[str.length()-1] == '#')break;
	}
	for(int i = 0;i < N;i++){
		p.push_back(parcel(i, sum[i]));
	}
}

void computing(){
	sort(p.begin(), p.end(),cmp);
	int k = 0;
	while(p.size() > 0){
		if(p.size() == 1){
			ans[k] = p[0].letter;
			break;
		}
		int t1 = p[0].letter , t2 = p[1].letter;
		if(t1 < t2){
			ans[k] = t1;
			for(int i = 2;i < p.size();i++){
				if(p[i].total == p[1].total){
					t2 = p[i].letter;
				}else{
					break;
				}
			}
			ans[N-1-k] = t2;
		}else{
			ans[k] = t2;
			ans[N-1-k] = t1;
		}
		for(vector<parcel>::iterator it = p.begin();it != p.end();it++){
			if(it->letter == t1 || it->letter == t2){
				p.erase(it);
				it--;
			}
		}
		k++;
	}
	cout << char(ans[0]+'A');
	for(int i = 1;i < N;i++){
		cout << " " << char(ans[i]+'A');
	}
	cout << endl << sum[ans[0]];
	for(int i = 1;i < N;i++){
		cout << " " << sum[ans[i]];
	}
	cout << endl;
}

int main(){
	//freopen("in" , "r" , stdin);
	int t;
	cin >> t;
	while(t--){
		initial();
		readcase();
		computing();
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值