杭电 1031【Design T-Shirt】

Design T-Shirt

problem Description
Soon after he decided to design a T-shirt for our Algorithm Board on Free-City BBS, XKA found that he was trapped by all kinds of suggestions from everyone on the board. It is indeed a mission-impossible to have everybody perfectly satisfied. So he took a poll to collect people's opinions. Here are what he obtained: N people voted for M design elements (such as the ACM-ICPC logo, big names in computer science, well-known graphs, etc.). Everyone assigned each element a number of satisfaction. However, XKA can only put K (<=M) elements into his design. He needs you to pick for him the K elements such that the total number of satisfaction is maximized.

Input
The input consists of multiple test cases. For each case, the first line contains three positive integers N, M and K where N is the number of people, M is the number of design elements, and K is the number of elements XKA will put into his design. Then N lines follow, each contains M numbers. The j-th number in the i-th line represents the i-th person's satisfaction on the j-th element.
 
Output
For each test case, print in one line the indices of the K elements you would suggest XKA to take into consideration so that the total number of satisfaction is maximized. If there are more than one solutions, you must output the one with minimal indices. The indices start from 1 and must be printed in non-increasing order. There must be exactly one space between two adjacent indices, and no extra space at the end of the line.
 
Sample Input
  
  
3 6 4 2 2.5 5 1 3 4 5 1 3.5 2 2 2 1 1 1 1 1 10 3 3 2 1 2 3 2 3 1 3 1 2
 
Sample Output
  
  
6 5 3 1 2 1
  
/*
*Design T-Shirt:输入N M K,N为打分的人数,M为需打分的T恤数量,k为所需选取出的T恤数量
*选取要求为:选取出K个分数最高的T恤,如果两个T恤分数一样,优先输出序号小的T恤,并且最后K个T恤顺序从高往低输出
*至少要进行两次排序
*
*输入
3 6 4
2 2.5 5 1 3 4
5 1 3.5 2 2 2
1 1 1 1 1 10

3 3 2
1 2 3
2 3 1
3 1 2
*输出
6 5 3 1
2 1
*
*/
#include<iostream>
using namespace std;
int main()
{
	//n,m,k对应题目要求的N,M,K为打分人数,T恤人数,所需选取的T恤数量,i,j为方便运算的变量
	int n,m,k,i,j;
	//注意打分类型为小数,middle作为运算的中间值寄存器
	double middle[2];
	//输入所需参数
	cin>>n>>m>>k;
	//根据m中的值动态分配一个array数组用于存放所打分数-------最后记得用delete关闭new动态分配出的空间
	double *array=new double[m];
	//根据m中的值动态分配一个二维数组number用于存放T恤所得分数总值和以及T恤的序号-------最后记得用delete关闭new动态分配出的空间
	double (*number)[2]=new double[m][2];
	//根据k的值动态分配一个sequence排序数组用于最后的输出排序-------最后记得用delete关闭new动态分配出的空间
	double *sequence=new double[k];
	//通过m以内的for循环,对number中存放分数的区域清零,对存放序号的区域按序赋值
	for(i=0;i<m;i++)
	{
		//number数组中第一列用于存放分数总值,第二例用于存放序号
		number[i][0]=0;
		number[i][1]=i+1;
	}
	//n代表人数,通过n以内的for循环对每个人所打的分数进行加值运算
	for(i=0;i<n;i++)
	{
		//m代表T恤的数量,通过m以内的for循环对所输入的T恤分数按序加和处理
		for(j=0;j<m;j++)
		{
			//从键盘获取T恤分数
			cin>>array[j];
			//number数组中的第一列通过加和处理得到某个T恤的总分值,注意需要自加
			number[j][0]+=array[j];
		}
		
	}
	//通过冒泡排序对分值由高到低,分值相同时序号由小到大排序处理
	for(i=0;i<m;i++)
	{
		//每进行一次冒泡排序所需排序的数值就减少一个
		for(j=1;j<m-i;j++)
		{
			//排序条件,小数往后排,即分值由高到低,分数相同时,序号大数往后排,即序号从小到大
			if(number[j-1][0]<number[j][0]||((number[j-1][0]==number[j][0])&&(number[j-1][1]>number[j][1])))
			{
				//middle作为两数交换时的中间值寄存器使用
				middle[0]=number[j-1][0];
				middle[1]=number[j-1][1];
				number[j-1][0]=number[j][0];
				number[j-1][1]=number[j][1];
				number[j][0]=middle[0];
				number[j][1]=middle[1];
			}
		}
	}
	//由于number中T恤所获打分已经按序从大到小排序,则通过k以内的for循环按照用户要求选取处前k大个T恤的序号存放在sequence排序数组中
	for(i=0;i<k;i++)
	{
		sequence[i]=number[i][1];
	}
	//同样对sequence数组进行从大到小的冒泡排序,方法与排序number数组时相同
	for(i=0;i<k;i++)
	{
		for(j=1;j<k-i;j++)
		{
			if(sequence[j-1]<sequence[j])
			{
				//sequence数组进行两个值的交换时,没有用到中间值寄存器,采用加和相减法
				sequence[j-1]+=sequence[j];
				sequence[j]=sequence[j-1]-sequence[j];
				sequence[j-1]=sequence[j-1]-sequence[j];
			}
		}
	}
	//对排序好的sequence数组进行输出
	for(i=0;i<k;i++)
	{
		cout<<sequence[i]<<" ";
	}
	cout<<endl;
	//最后用delete关闭用new所动态分配出的空间
	delete[] sequence;
	delete[] number;
	delete[] array;
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值