PKU3399贪心

原题http://poj.org/problem?id=3399

Product

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 2839   Accepted: 688   Special Judge

Description

There is an array of N integer numbers in the interval from -30000 to 30000. The task is to select K elements of this array with maximal possible product.

Input

The input consists of + 1 lines. The first line contains N and K (1 ≤ K ≤ N ≤
100) separated by one or several spaces. The others contain values of array elements.

Output

The output contains a single line with values of selected elements separated by one space. These values must be in non-increasing order.

Sample Input

4 2
1
7
2
0

Sample Output

7 2
//第一次写的时候想分类讨论,发现这是一个很复杂的问题,需要考虑的问题有很多
//第二次的时候想到了用找的方法。但是比赛的时候感觉到有点麻烦。所以就没写。。。现在想想,挺后悔的。
//本题的思路是先按绝对值进行排序。然后进行查询。如果说碰到了负的先记录。如果碰到正的,就放入

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <limits.h>
#include <ctype.h>
#include <string.h>
#include <string>
#include <math.h>
#include <algorithm>
#include <iostream>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <map>
#include <set>
using namespace std;
#define N 100 + 10

int abb(int a){
	if(a  < 0)
		return -a;
	else
		return a;
}

int cmp(int a,int b){
	return abb(a) < abb(b);
}

int main(){
	int n,k;
	int i;
	int num[N],ans[N],f[5];

	while(~scanf("%d%d",&n,&k)){
		memset(num,0,sizeof(num));
		memset(ans,0,sizeof(ans));
		memset(f,0,sizeof(f));
		for(i=0;i<n;i++){
			scanf("%d",&num[i]);
		}
		sort(num,num+n,cmp);
		int l = 0;
		int flag = 0;
		for(i=n-1;i>=0&&l<k;i--){
			if(num[i]<0 && flag==0){
				f[0] = num[i];
				flag = 1;
			}
			else if(num[i]<0 && flag==1 && l+2<=k){//如果放的下就直接放下
				ans[l++] = f[0];
				ans[l++] = num[i];
				flag = 0;
			}
			else if(num[i]<0 && flag==1 && l+2>k){//如果不够了,那就就要进行判断。选择最优解
				int j,x;
				for(j=i-1;j>=0;j--){
					if(num[j] >= 0){
						break;
					}
				}
				for(x=l-1;x>=0;x--){
					if(ans[x] >= 0){//楼了个等于。。。。
						break;
					}
				}
				if(x>=0 && j>=0){
					if(num[j]*ans[x] >= f[0]*num[i]){
						ans[l++] = num[j];
					}
					else{
						ans[l++] = num[i];
						ans[x] = f[0];
					}
				}
				flag = 0;
			}
			else if(num[i] > 0){
				ans[l++] = num[i];
			}
		}
		if(l < k){//如果案例为5 5 3 2 1 0 0
			for(i=0;i<k;i++){
				ans[i] = num[i];
			}
		}
		sort(ans,ans+k);
		for(i=k-1;i>=0;i--){
			if(i != 0){
				printf("%d ",ans[i]);
			}
			else{
				printf("%d\n",ans[i]);
			}
		}
	}

	return 0;
}

PKU3399贪心

时间: 2024-10-12 03:02:00

PKU3399贪心的相关文章

【uva 1615】Highway(算法效率--贪心 区间选点问题)

题意:给定平面上N个点和一个值D,要求在x轴上选出尽量少的点,使得对于给定的每个店,都有一个选出的点离它的欧几里德距离不超过D. 解法:先把问题转换成模型,把对平面的点满足条件的点在x轴的直线上可得到一个个区间,这样就是选最小的点覆盖所有的区间的问题了.我之前的一篇博文有较详细的解释:关于贪心算法的经典问题(算法效率 or 动态规划).代码实现我先空着.挖坑~

【贪心+Treap】BZOJ1691-[Usaco2007 Dec]挑剔的美食家

[题目大意] 有n头奶牛m种牧草,每种牧草有它的价格和鲜嫩度.每头奶牛要求它的牧草的鲜嫩度要不低于一个值,价格也不低于一个值.每种牧草只会被一头牛选择.问最少要多少钱? [思路] 显然的贪心,把奶牛和牧草都按照鲜嫩度由大到小排序,对于每奶牛把鲜嫩度大于它的都扔进treap,然后找出后继. 不过注意后继的概念是大于它且最小的,然而我们这里是可以等于的,所以应该是找cow[i].fresh-1的后继,注意一下…… 1 #include<iostream> 2 #include<cstdio&

POJ1017 Packets(贪心算法训练)

Time Limit: 1000MS          Memory Limit: 10000K          Total Submissions: 51306          Accepted: 17391 Description A factory produces products packed in square packets of the same height h and of the sizes 1*1, 2*2, 3*3, 4*4, 5*5, 6*6. These pro

ZOJ 3946 Highway Project 贪心+最短路

题目链接: http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3946 题解: 用dijkstra跑单元最短路径,如果对于顶点v,存在一系列边(ui,v)使得dis[v]最小(dis[v]表示0到v的距离).这些边能且只能选一条,那么我们自然应该选cost最小的那个边了. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #inc

CoderForce 140C-New Year Snowmen(贪心)

题目大意:有n个已知半径的雪球.堆一个雪人需要三个尺寸不同的雪球,问用这些雪球最多能堆多少个雪人? 题目分析:先统计一下每种尺寸的球的个数,从三种最多的种类中各取出一个堆成雪人,这样贪心能保证的到的数目最多. 代码如下: # include<iostream> # include<map> # include<vector> # include<cstdio> # include<queue> # include<algorithm>

计蒜客 跳跃游戏(贪心)

给定一个非负整数数组,假定你的初始位置为数组第一个下标.数组中的每个元素代表你在那个位置能够跳跃的最大长度. 请确认你是否能够跳跃到数组的最后一个下标. 例如: A = [2,3,1,1,4], return ture A = [3,2,1,0,4], return false. 格式: 第一行输入一个正整数n,接下来的一行,输入数组A[n].如果能跳到最后一个下标,输出"true",否则输出"false" 样例1 ????输入:???? ????????5 ???

BZOJ 2525 [Poi2011]Dynamite 二分+树形贪心

题意: n个点,一棵树,有些点是关键点,可以将m个点染色. 求所有关键点到最近的被染色点的距离的最大值最小. 解析: 反正从这道题我是学了一种做题思路? 大爷讲课的时候说的:一般选择某些点的代价相同的话都是贪心,代价不同的话一般都是DP. 想想也挺对的,不过就是没有感悟到过? 反正这题考试的时候我是直接D了贪心的- -! 忘了为啥D了. 显然最大值最小我们需要二分一下这个值. 然后接下来我们从下往上扫整棵树. 节点的状态有几个? 第一种是 子树内没有不被覆盖的关键点,并且子树中有一个节点的贡献可

CF 500 C. New Year Book Reading 贪心 简单题

New Year is coming, and Jaehyun decided to read many books during 2015, unlike this year. He has n books numbered by integers from 1 to n. The weight of the i-th (1 ≤ i ≤ n) book is wi. As Jaehyun's house is not large enough to have a bookshelf, he k

贪心 --- HNU 13320 Please, go first

Please, go first Problem's Link: http://acm.hnu.cn/online/?action=problem&type=show&id=13320 Mean: n个人一起去滑雪,要坐电梯到山顶,电梯每5分钟可以送一个人上去.这n个人中有的是组好团一起滑雪的,所以要等到齐了才能开始滑. 但是他们到达电梯下的时间都不是统一的,对于单独一个人来说,他在山下等和在山上等的时间都是一样的. 但是对于n个人的集体来说,如果让他后面的人先上去,这样可能会更节省时间.