HDU-5210-Delete(Oier)

Delete

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 203    Accepted Submission(s): 138


Problem Description
WLD likes playing with numbers. One day he is playing with  N  integers. He wants to delete  K  integers from them. He likes diversity, so he wants to keep the kinds of different integers as many as possible after the deletion. But he is busy pushing, can you help him?
 

Input
There are Multiple Cases. (At MOST  100 )

For each case:

The first line contains one integer  N(0<N100) .

The second line contains  N  integers  a1,a2,...,aN(1aiN) , denoting the integers WLD plays with.

The third line contains one integer  K(0K<N) .
 

Output
For each case:

Print one integer. It denotes the maximum of different numbers remain after the deletion.
 

Sample Input
   
   
   
   
4 1 3 1 2 1
 

Sample Output
   
   
   
   
3
Hint
if WLD deletes a 3, the numbers remain is [1,1,2],he'll get 2 different numbers. if WLD deletes a 2, the numbers remain is [1,1,3],he'll get 2 different numbers. if WLD deletes a 1, the numbers remain is [1,2,3],he'll get 3 different numbers.
 

Source
BestCoder Round #39 ($)
 

Recommend
hujie   |   We have carefully selected several similar problems for you:   5213  5212  5211  5209  5208 


看了一下日期,距离上一回AC应该是20天了,蓝桥已跪,败局已成,但生命不止,ac不止!这一段时间也想了很多,我想也许有很多很多的Oier和我一样,付出了努力,但是可能缺乏那么一点点的比赛的天赋或者运气,与梦想失之交臂!但不论怎样,你ac过!你思考过!AC同样是也是一种心态,在你感到烦闷或者烦躁的时候,静下心来,a一道题,也许不是什么特别高级的算法,但是却能给心灵带来宁静与慰藉,生命不止,ac不止!即使我不能成为楼教主那样的顶尖高手,但是我能很从容的说,我是一名Oier!自己选择的路!跪着也要走完!

好了言归正传,这题是BestCoder上面的第一道题:
官方给出的答案是:
1001 Delete
用一个cnt数组记下每个数在a序列中出现了几次
在删数的时候贪心,尽可能删那些出现次数>1的数
这样就可以使最后有最多不同的数

这个思路很简单,我们首先要求出a序列中每个数出现的次数,
然后在删除k个数的时候贪心(即尽可能删除那些出现次数>1的数,
只要存在出现次数大于1,看k是否大于或者等于最小次数的出现次数,
如果满足条件,则k减去大于或者等于最小次数的出现次数,sum1记录
释放的相同数的个数,sum2记录不重复的数字个数)

这里要考虑两种情况(就是个坑,一个陷阱!):
1.存在k大于或者等于最小次数的出现次数

例如示例:

输入:
4
1   3   1    2
1
输出:
3

这个时候输出的最多剩下的不同的个数为sum2-k+sum1

2.不存在k大于或者等于最小次数的出现次数

例如示例:

输入:
6
1   1   1   1   1   1   2
1
输出:
2

这个时候输出的最多剩下不同的个数为j+1,因为此时k这个变量没用因为它不能释放次数最小的那个相同数,即k一个相同数都释放不了
即最后剩下的不同个数为j+1,(j为不同个数数组的下标)

import java.io.*;
import java.util.*;

public class Main
{

	public static void main(String[] args)
	{
		// TODO Auto-generated method stub
		Scanner input = new Scanner(System.in);
		while(input.hasNext())
		{
			int n = input.nextInt();
			int a[] = new int[n];             //记录输入的数
			int cnt[] = new int[n];          //记录每个数出现的次数
			for(int i=0;i<n;i++)
			{
				a[i]=input.nextInt();
			}
			int k =input.nextInt();
			int j=0;                          //cnt数组计数器 
			Arrays.sort(a);
			for(int i=1;i<n;i++)              //记录每个数出现的次数,按a[i]的从小到大排列
			{
				if(a[i]==a[i-1]) 
				{
					cnt[j]++;
				}
				else
				{
					j++;
				}
			}	
			
	//		System.out.println("j="+j);
			
			
			int temp[] = new int[j+1];           //创建一个j大小的数组为了实现快排,temp数组复制于cnt数组
			for(int i=0;i<=j;i++)
			{
				temp[i]=cnt[i];
			}
			Arrays.sort(temp);                    //快速排序
			
			int sum1=0;                           //记录释放了几个相同数
			int sum2=0;                           //记录本身就不同的数!
			boolean flag = true;                  //判断是否能够释放相同数
			for(int i=0;i<=j;i++)
			{
				if(cnt[i]>0)
				{
					if(k>=cnt[i])
					{
						k=k-cnt[i]; 
						sum1++;           //释放了几个相同数
					}
					else
					{
						flag=false;
						break;
					}
				}
				else
				{
					sum2++;                  //记录只有一个的数
				}
			}
			if(flag)
				System.out.println(sum2-k+sum1);
			else
			{
				System.out.println(j+1);
			}
		}
	}
}

中文题如下:

Delete

 
 Accepts: 543
 
 Submissions: 1111
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
wld有n个数(a1, a2, ...,an),他希望进行k次删除一个数的操作,使得最后剩下的n-k个数中有最多的不同的数,保证1 \leq n \leq 100,0 \leq k < n,1 \leq ai \leq n(对于任意1 \leq i \leq n)
输入描述
多组数据(最多100组)
对于每组数据:
第一行:一个数n表示数的个数
接下来一行:n个数,依次为a1, a2, … ,an
接下来一行:一个数k表示操作数
输出描述
对于每组数据:
输出最多剩下的不同的数的个数
输入样例
4
1 3 1 2 
1
输出样例
3
Hint
如果删去第一个1:
在[3,1,2]中有3个不同的数
如果删去3:
在[1,1,2]中有2个不同的数
如果删去第二个1:
在[1,3,2]中有3个不同的数
如果删去2:
在[1,3,1]中有1个不同的数


 

你可能感兴趣的:(java,HDU,BestCoder,AC不止,保持ac的心态)