POJ1010 Stamps

本文介绍了一个邮票分配问题的解决方案,旨在为客户提供精确且多样化的邮票组合,以满足其特定金额需求。通过枚举所有可能的邮票组合,算法确保了在不超过四张邮票的前提下,提供最大数量的不同类型邮票。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

STAMPS

Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 12883 Accepted: 3544

Description

Have you done any Philately lately?

You have been hired by the Ruritanian Postal Service (RPS) to design their new postage software. The software allocates stamps to customers based on customer needs and the denominations that are currently in stock.

Ruritania is filled with people who correspond with stamp collectors. As a service to these people, the RPS asks that all stamp allocations have the maximum number of different types of stamps in it. In fact, the RPS has been known to issue several stamps of the same denomination in order to please customers (these count as different types, even though they are the same denomination). The maximum number of different types of stamps issued at any time is twenty-five.

To save money, the RPS would like to issue as few duplicate stamps as possible (given the constraint that they want to issue as many different types). Further, the RPS won't sell more than four stamps at a time.

Input

The input for your program will be pairs of positive integer sequences, consisting of two lines, alternating until end-of-file. The first sequence are the available values of stamps, while the second sequence is a series of customer requests. For example:

1 2 3 0 ; three different stamp types
7 4 0 ; two customers
1 1 0 ; a new set of stamps (two of the same type)
6 2 3 0 ; three customers

Note: the comments in this example are *not* part of the data file; data files contain only integers.

Output

For each customer, you should print the "best" combination that is exactly equal to the customer's needs, with a maximum of four stamps. If no such combination exists, print "none".
The "best" combination is defined as the maximum number of different stamp types. In case of a tie, the combination with the fewest total stamps is best. If still tied, the set with the highest single-value stamp is best. If there is still a tie, print "tie".

For the sample input file, the output should be:

7 (3): 1 1 2 3
4 (2): 1 3
6 ---- none
2 (2): 1 1
3 (2): tie

That is, you should print the customer request, the number of types sold and the actual stamps. In case of no legal allocation, the line should look like it does in the example, with four hyphens after a space. In the case of a tie, still print the number of types but do not print the allocation (again, as in the example).Don't print extra blank at the end of each line.

Sample Input

1 2 3 0	; three different stamp types
7 4 0		; two customers
1 1 0		; a new set of stamps (two of the same type)
6 2 3 0	; three customers

Sample Output

7 (3): 1 1 2 3 
4 (2): 1 3 
6 ---- none
2 (2): 1 1
3 (2): tie

Source

 

 

解题思路:

    直接枚举所有可能的4张(或4张以下)邮票的组合就行了。我提交速度是32MS,由于使用了vector等结构,这个速度并不算快,如果直接上数组的话,应该会快好多。

    另外,需要注意的是,这道题目很容易出错,有许多细节需要注意的,我的程序WA了好多次,每次WA之后看POJ后面的Discuss中给出的测试数据,找出bug修改。这样经过了N次之后,终于AC了。上代码。

 

/*
 * main.cpp
 *
 *  Created on: 2012-7-18
 *      Author: wwf
 */

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

void solve(vector<int> &, int );

int main(void) {
	while (!cin.eof()) {

		int input;
		int request;
		vector<int> stamps;
		for (cin >> input; input != 0; cin >> input) {//input all the stamps
			stamps.push_back(input);
		}

		for (cin >> request; request != 0; cin >> request) {//for each customer request

			solve(stamps,request);

		}

	}
}

void solve(vector<int> &stamps, int request) {

	int best_types_choosen = 0;
	int best_total_stamps = 0;
	int best_highest_single = 0;
	vector<int> best_choice;

	int sum_combinition = 0;
	int types_choosen = 0;

	bool tie=false;

	for (int i1 = 0; i1 < stamps.size(); i1++) {
		sum_combinition += stamps[i1];
		types_choosen = 1;
		//判断胜利与否
		if (sum_combinition == request) {
			if(types_choosen==best_types_choosen&&best_total_stamps==1&&best_highest_single==stamps[i1]){
				//tie
				tie=true;
			}else if(types_choosen>best_types_choosen||
					 (types_choosen==best_types_choosen&&best_total_stamps>1)||
					 (types_choosen==best_types_choosen&&best_total_stamps==1&&best_highest_single<stamps[i1])
					){
				//win
				tie=false;
				best_types_choosen = types_choosen;
				best_total_stamps = 1;
				best_highest_single = stamps[i1];
				best_choice.clear();
				best_choice.push_back(i1);
			}else{
				//do nothing
			}
		} else if (sum_combinition < request) {
			for (int i2 = i1; i2 < stamps.size(); i2++) {
				sum_combinition += stamps[i2];
				if (i2 != i1)
					types_choosen++;
				//判断胜利与否
				if (sum_combinition == request) {

					if(types_choosen==best_types_choosen&&best_total_stamps==2&&best_highest_single==max(stamps[i1],stamps[i2])){
						//tie
						tie=true;
					}else if(types_choosen>best_types_choosen||
							 (types_choosen==best_types_choosen&&best_total_stamps>2)||
							 (types_choosen==best_types_choosen&&best_total_stamps==2&&best_highest_single<max(stamps[i1],stamps[i2]))
							){
						//win
						tie=false;
						best_types_choosen = types_choosen;
						best_total_stamps = 2;
						best_highest_single = max(stamps[i1],stamps[i2]);
						best_choice.clear();
						best_choice.push_back(i1);
						best_choice.push_back(i2);
					}else{
						//do nothing
					}
				} else if (sum_combinition < request) {
					for (int i3 = i2; i3 < stamps.size(); i3++) {
						sum_combinition += stamps[i3];
						if (i3 != i2)
							types_choosen++;
						//判断胜利与否
						if (sum_combinition == request) {


							if(types_choosen==best_types_choosen&&best_total_stamps==3&&best_highest_single==max(stamps[i1],max(stamps[i2],stamps[i3]))){
								//tie
								tie=true;
							}else if(types_choosen>best_types_choosen||
									 (types_choosen==best_types_choosen&&best_total_stamps>3)||
									 (types_choosen==best_types_choosen&&best_total_stamps==3&&best_highest_single<max(stamps[i1],max(stamps[i2],stamps[i3])))
									){

								//win
								tie=false;
								best_types_choosen = types_choosen;
								best_total_stamps = 3;
								best_highest_single = max(stamps[i1],max(stamps[i2],stamps[i3]));
								best_choice.clear();
								best_choice.push_back(i1);
								best_choice.push_back(i2);
								best_choice.push_back(i3);
							}else{
								//do nothing
							}
						} else if (sum_combinition < request) {
							for (int i4 = i3; i4 < stamps.size(); i4++) {
								sum_combinition += stamps[i4];
								if (i4 != i3)
									types_choosen++;

								//判断胜利与否
								if (sum_combinition == request) {
									if(types_choosen==best_types_choosen&&best_total_stamps==4&&best_highest_single==max(stamps[i1],max(stamps[i2],max(stamps[i3],stamps[i4])))){
										//tie
										tie=true;
									}else if(types_choosen>best_types_choosen||
											 (types_choosen==best_types_choosen&&best_total_stamps>4)||
											 (types_choosen==best_types_choosen&&best_total_stamps==4&&best_highest_single<max(stamps[i1],max(stamps[i2],max(stamps[i3],stamps[i4]))))
											){
										//win
										tie=false;
										best_types_choosen = types_choosen;
										best_total_stamps = 4;
										best_highest_single = max(stamps[i1],max(stamps[i2],max(stamps[i3],stamps[i4])));
										best_choice.clear();
										best_choice.push_back(i1);
										best_choice.push_back(i2);
										best_choice.push_back(i3);
										best_choice.push_back(i4);
									}else{
										//do nothing
									}
								}
								if (i4 != i3)
									types_choosen--;
								sum_combinition -= stamps[i4];
							}
						}

						sum_combinition -= stamps[i3];
						if (i3 != i2)
							types_choosen--;
					}
				}

				sum_combinition -= stamps[i2];
				if (i2 != i1)
					types_choosen--;
			}
		}

		sum_combinition -= stamps[i1];
	}

	if(best_types_choosen==0){
		cout<<request<<" ---- none"<<endl;
	}else if(tie){
		cout<<request<<" ("<<best_types_choosen<<"): tie"<<endl;
	}else{
		cout<<request<<" ("<<best_types_choosen<<"):";
		for(vector<int>::iterator it=best_choice.begin();it!=best_choice.end();it++){
			cout<<" "<<stamps[(*it)];
		}
		cout<<endl;
	}
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值