蓝桥杯历届试题 对局匹配 100分 并解释50分原因 java实现

问题描述

  小明喜欢在一个围棋网站上找别人在线对弈。这个网站上所有注册用户都有一个积分,代表他的围棋水平。


  小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是K的两名用户匹配在一起。如果两人分差小于或大于K,系统都不会将他们匹配。


  现在小明知道这个网站总共有N名用户,以及他们的积分分别是A1, A2, ... AN。


  小明想了解最多可能有多少名用户同时在线寻找对手,但是系统却一场对局都匹配不起来(任意两名用户积分差不等于K)?

输入格式

  第一行包含两个个整数N和K。
  第二行包含N个整数A1, A2, ... AN。


  对于30%的数据,1 <= N <= 10
  对于100%的数据,1 <= N <= 100000, 0 <= Ai <= 100000, 0 <= K <= 100000

输出格式

  一个整数,代表答案。

样例输入

10 0
1 4 2 8 5 7 1 4 2 8

样例输出

6

问题解析:

1.相距k为相邻,这就出现问题了 举个例子: (50分原因)

n=2 k=2  

1  5

ans=1;

但实际上其应该为2

即1 5并不相邻  但我们分组的时候可能把他们分成相邻的   

解决方法很简单,就是即使这个积分temp不存在,依旧在数组上保留这个值即value[temp]=0;

2.弄懂上一个问题这题就很简单了,就是找到元积分0到k-1,其他积分可以由这些积分+N*k(N>=1)得到,分成k组

然后对每一组进行动态规划 

j=0  dp[j]=value[0];

j=1 dp[j]=max(dp[0],value[j]);

j>1 dp[j]=max(dp[j-2]+value[j],dp[j-1])

//阶段变量 j  决策变量 dp[j]:对于j积分来说, 每组最大满足没有对局的登录人数

话不多说,代码如下



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;


public class Main {
//对局匹配
//100points
final static int maxn=100000;
	
	public static void main(String[] args) throws IOException  {
		int n,k;
		int c[]=new int[maxn+5];//c[j]表示积分为j的人数
		BufferedReader bfr=new BufferedReader(new InputStreamReader(System.in));
		String str=bfr.readLine();
		String s[]=str.split(" ");
		n=Integer.parseInt(s[0]);
		k=Integer.parseInt(s[1]);
		
		str=bfr.readLine();
		s=str.split(" ");
		int max=-1;//保存最大的积分,便于后续分组时作为最后一个判定的标准。
		for(int i=0;i<n;i++)
		{
			int temp=Integer.parseInt(s[i]);
				c[temp]++;
			max=Math.max(max, temp);
		}
		int ans=0;
		if(k==0)//分类讨论
			{
				for(int i=0;i<=max;i++)
				{
					if(c[i]!=0)
						ans++;
				}
			}
		else
		{
	         
	        int dp[]=new int [maxn+5];//每组人员的同时在线最大数
	        for(int i=0;i<k;i++)//积分 从0到k-1 k=0+k 已遍历到,依次类推
	        {
	        	int id=0;
	        	int value[]=new int [maxn+5];//value[i]=j :表示i这个数共有j个
	        	for(int j=i;j<=max;j+=k)//j:积分
	        	{
	        	//if(c[j]!=0) //这个操作可能会导致不是相邻k的值变为相邻 eg n=2 k=2 1 5 //ans=1;但实际上其应该为2
	        			value[id++]=c[j];//a[id]中有可能为0,不过不影响动态规划
	        	}
	        	
	        	for(int j=0;j<id;j++)
	        	{
	        		if(j==0)
	        			dp[j]=value[j];
	        		else if(j==1)
	        			dp[j]=Math.max(dp[j-1],value[j]);
	        		else
	        			dp[j]=Math.max(dp[j-2]+value[j], dp[j-1]);
	        	}
	        	if(id!=0)
	        		ans+=dp[id-1];
	        }
		}
		System.out.println(ans);
		
	}
}

评测详情:

详细记录
评测点序号 评测结果 得分 CPU使用 内存使用 下载评测数据
1 正确 12.50 140ms 21.00MB 输入 输出
2 正确 12.50 203ms 20.76MB VIP特权
3 正确 12.50 171ms 21.46MB VIP特权
4 正确 12.50 250ms 24.74MB VIP特权
5 正确 12.50 390ms 37.30MB VIP特权
6 正确 12.50 390ms 34.76MB VIP特权
7 正确 12.50 281ms 34.98MB VIP特权
8 正确 12.50 406ms 35.60MB VIP特权

感受:

遇到问题不要慌,多进行逻辑分析,一般都没有什么问题,还有做事要持之以恒,才会有所成!

猜你喜欢

转载自blog.csdn.net/Look_star/article/details/88404717
今日推荐