首页 > 试题广场 >

庆祝61

[编程题]庆祝61
  • 热度指数:2174 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
牛家庄幼儿园为庆祝61儿童节举办庆祝活动,庆祝活动中有一个节目是小朋友们围成一个圆圈跳舞。牛老师挑选出n个小朋友参与跳舞节目,已知每个小朋友的身高h_i。为了让舞蹈看起来和谐,牛老师需要让跳舞的圆圈队形中相邻小朋友的身高差的最大值最小,牛老师犯了难,希望你能帮帮他。
如样例所示:
当圆圈队伍按照100,98,103,105顺时针排列的时候最大身高差为5,其他排列不会得到更优的解

输入描述:
输入包括两行,第一行为一个正整数n(3 ≤ n ≤ 20)
第二行为n个整数h_i(80 ≤ h_i ≤ 140),表示每个小朋友的身高。


输出描述:
输出一个整数,表示满足条件下的相邻小朋友身高差的最大值。
示例1

输入

4
100 103 98 105

输出

5
//这个很简单啊!怎么样身高差最小呢?就是两身高差不多的人站一起咯,小时候站队 老师总让
//矮的站中间高的站两边,就是这个道理,如 9 8 7 6 6 7 8 9然后9和9再拉手不就可以了吗 !所以
//将数据输入一个数组如【8 9 7 6 5 4 3 2】然后排序【2 3 4 5 6 7 8 9】然后遍历数组进入
//一个队列一个栈 现规定,索引为0,2,4,,,的依次进入队列Q1,索引为1,3,5,,,,的依次进入//栈S1,就形成一个队列2 4 6 8 (队列尾为8)和一个栈3 5 7 9(栈顶为9) 。然后出栈9 7 5 3 
//依次进入队列尾 形成 2 4 6 8 9 7 5 3 就排队成功,2和3拉手就成圈,求每个元素与挨着的
//距离就可以了

发表于 2017-07-17 11:24:20 回复(2)
看了叫声萤草爸爸 的答案,完全没看懂,自己试了试怎么排才终于找到思路:
为了使左右差最小应该怎么排?
首先该想到序号间隔越小差值也越小.
所以应该按顺序左右插入,这样形成一种金子塔型, 这样序号差值最大就只有2了,
如有 1,2,3,4,5,6.7.应该排成7,5,3,1,2,4,6或1,3,5,7,6,4,2.

所以答案是在如下几项中最大值(已排序):
h[1]-h[0]和h[n-1]-h[n-1]和所有序号间隔为2的差.



#include<bits/stdc++.h>
using namespace std;
int main(){
	int n;
	cin >> n;
	vector<int> h(n);
	for (int i = 0; i<n; i++){
		cin >> h[i];
	}

	sort(h.begin(), h.end());

	int a = h[1] - h[0];
	int b = h[n - 1] - h[n - 2];
	int maxVal = max(a, b);
	for (int i = 0; i<n - 2; i++){
		int c = h[i + 2] - h[i];
		maxVal = max(maxVal, c);
	}
        cout<<maxVal;
	return 0;
}

编辑于 2017-06-25 12:48:58 回复(2)
分析:对于给定的序列:1、3、5、4、7、6、2,假设是此序列已经是按升序排好的:1、2、3、4、5、6、7。
序号位置间隔越小其差值越小 ,要想整体两两间隔最小,可以将有序的序列从头到尾分别按 左右顺序 插入到一个新的序列中,这样形成一种金字塔型。

首先将原始序列按升序排列,同时假设一个与原序列大小相同的序列b,过程如下:
               a:  1    2    3    4    5    6    7
               b:
          下标:  0    1    2    3    4    5    6
第一次插入: 1                                   2
第二次插入: 1     3                       4    2
第三次插入:  1   3     5          6      4    2
第四次插入:  1   3    5      7   6     4    2
最终b序列为: 1   3     5     7   6      4    2
最后我们将b序列从第二个位置开始向后遍历,判断当前位置和其前面一个位置的差值,注意题目是要围成一个圈,所以最后还需要判断最后一个位置和第一个位置的差值。差值最大的值即为所求的值。参考代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
int main()
  {
     int n;
     while(cin>>n)
     {
       int a[n];
       int b[n];
       for(int i=0;i<n;i++)
          cin>>a[i];
       sort(a,a+n);
       int j=0; 
       int k=n-1;
       for(int i=0;i<n;i++)
         {
            if(i%2==0)
              { 
                b[j]=a[i];
                j++;
              }
           else
              {
                b[k]=a[i];
                k--;
              }
         }
       int maxHeiRes=abs(b[1]-b[0]); //注意要加绝对值,因为数组b前向后之差可能为负值
       for(int i=2;i<n;i++)
        {
          int temp=abs(b[i]-b[i-1]);
          if(temp>maxHeiRes)
              maxHeiRes=temp;
        }
       int temp1=abs(b[n-1]-b[0]);
       if(maxHeiRes<temp1)
          maxHeiRes=temp1;
       cout<<maxHeiRes<<endl;
     }
  }

编辑于 2017-07-03 15:29:40 回复(0)

//要想小朋友的身高差尽量小,在升序排好队后,应该让小朋友错位排队

//举例来说,如果有5个小朋友,1 2 3 4 5,首先肯定要避免1与5在一起,所以4和3要插在1与5之间

//那么2是放在4与1之间呢,还是3与1之间呢?

//如图,因为4与1的差肯定大于4与2或3与1的差,所以2肯定要排在1与4之间

   vs  
//依次类推,为了使身高差尽量小,必需如图,错位排队,当然别忘了最小的两个数,与最大的两个数的差值

//代码如下
import java.util.Arrays; 

import java.util.Scanner;


public class Main {


public static void main(String[] args){

Scanner in=new Scanner(System.in);

int n=in.nextInt();

int[] h=new int[n];

for(int i=0;i<n;i++){

h[i]=in.nextInt();

}

Arrays.sort(h);

int max=Math.max(h[1]-h[0],h[n-1]-h[n-2]);

for(int i=0;i<n-2;i++){

max=Math.max(max, h[i+2]-h[i]);

}

System.out.println(max);

}

}

发表于 2017-06-17 12:49:17 回复(1)
两个链接参考学习
import sys
n = int(sys.stdin.readline())
nums = list(map(int,sys.stdin.readline().strip().split()))
nums.sort()
maxValue = 0
for i in range(2,n):
    maxValue =  max(maxValue,nums[i] - nums[i-2])
print(maxValue)
发表于 2019-07-18 19:04:09 回复(0)
大家代码都写得不错,我就不贴了,写一个简单的证明吧
当a[0] <= a[1] <= ... <= a[n]时,按如下方式排列最大差值最小
a[0] a[1]
a[2] a[3]
...
a[n-1]

采用数学归纳法
当n==3时,显然成立
假设当n==k时,结论成立,并且最大差值为A[k]=a[i] - a[i-2];
任取一个不同的排列b[0] b[1] b[2] ... b[k-1],其中{ b[0], ..., b[k-1] } == { a[0], ..., a[k-1] },设其最大差值为B[k]=abs(b[j]-b[j-1]),有B[k] >= A[k];
首先将a[k]插入A中,则有A[k+1]=max(A[k], a[k]-a[k-2]);
然后将a[k]插入B中,无论选择何处,都有B[k+1]>=B[k];
如果A[k+1]==A[k],那么B[k+1]>=A[k+1];
如果A[k+1]==a[k]-a[k-2],考虑a[k]在B中的情形:
... b[m] a[k] b[m+1] ...
B[k+1] = max(B[k], a[k]-b[m], a[k]-b[m+1]),显然当b[m]与b[m+1]是a[k-2]和a[k-1]时,B[k+1]最小,此时B[k+1]=max(B[k], a[k]-a[k-2]) >= A[k+1];
所以n==k+1时结论也成立;
综上所述,对任意n>=3,结论都成立。


编辑于 2017-09-28 21:32:35 回复(0)
/*最高的旁边一定是第二高的和第三高的啊 
第二高的旁边一定是第一高和第4高的啊
所以解析如下*/

#include <iostream>
using namespace std;
intmain(){
    intn;
    cin >> n;
    intinput[20] = {};
    intcurrent;
    for(inti = 0; i < n; i++)
    {
        cin >> input[i];
        for(intk = 0; k < i; k++)
        {
            if(input[k] < input[i])
            {
                intcurrent = input[i];
                for(intj = k; j < i + 1; j++)
                {
                    intmm = input[j];
                    input[j] = current;
                    current = mm;
                }
                break;
            }
        }
    }
    intout = 0;
    for(inti = 0; i < n - 2; i++)
    {
        if(out < input[i] - input[i + 2])
            out = input[i] - input[i + 2];
    }
    cout << out;
    return0;
}
发表于 2017-07-19 08:52:07 回复(0)
#include<iostream>
#include<math.h>
using namespace std;
int partition(int* p,int i,int j){
    int pivot = p[i];
    while(i<j){
        while(i<j&&p[j]>=pivot)
            j--;
        if(i<j)
            p[i++]=p[j];
        while(i<j&&p[i]<=pivot)
            i++;
        if(i<j)
            p[j--]=p[i];
    }
    p[i]=pivot;
    return i;
}
void quicksort(int* p,int low,int high){
    int pivotpos;
    if(low<high){
        pivotpos = partition(p,low,high);
        quicksort(p,low,pivotpos-1);
        quicksort(p,pivotpos+1,high);
    }
}
int main(){
    int n;
    cin>>n;
    int a[n];
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    quicksort(a,0,n-1);
    int b[n];
    for(int m=0,i=0,j=n-1;i<=j;i++,j--,m++){
        b[i]=a[m];
        m++;
        if(m>n-1||i==j)break;
        b[j]=a[m];
    }
    int max= 0;
    for(int i=1;i<=n-1;i++){
        if(abs(b[i]-b[i-1])>max) max=abs(b[i]-b[i-1]);
    }
    if(abs(b[n-1]-b[0])>max) max=abs(b[n-1]-b[0]);
                                     cout<<max<<endl;
                                     return 0;
}

发表于 2017-07-11 17:15:51 回复(0)
// 思路: 先把所有的身高从大到小排列,分别为0-(n-1),则最大值(n-1)左右分别为(n-2)和(n-3)
//        即....(n-4)、(n-2)、(n-1)、(n-3)、(n-5)...   然后最小的两个值围成一圈

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;


public class Main {
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {//注意while处理多个case
        	int num = in.nextInt();
        	ArrayList<Integer> heights = new ArrayList<Integer>();
        	for(int i=0;i<num;i++){
        		heights.add(in.nextInt());
        	}
        	Collections.sort(heights);
        	int max = -1;
        	// 倒数第一大
        	int cha = Math.abs(heights.get(num-1)-heights.get(num-2));
        	int tmp = num-2;
            while(tmp>1){
            	cha = Math.abs(heights.get(tmp)-heights.get(tmp-2));
            	if(cha>max)
            		max = cha;
            	tmp = tmp-2;
            }
            tmp = num-1;
            while(tmp>1){
            	cha = Math.abs(heights.get(tmp)-heights.get(tmp-2));
            	if(cha>max)
            		max = cha;
            	tmp = tmp-2;
            }
            cha = Math.abs(heights.get(0)-heights.get(1));
        	if(cha>max)
        		max = cha;
        	System.out.print(max);
        }
	}
}

编辑于 2017-06-17 11:31:50 回复(3)
import java.util.*;

public class Main{
	public static void main(String[] agrs) {
		Scanner input = new Scanner(System.in);
		int len = input.nextInt();
		input.nextLine();
		int[] nums = new int[len];
		for(int i = 0; i < len; i++) {
			nums[i] = input.nextInt();
		}
		Arrays.sort(nums);
		int pre = nums[1] - nums[0];
		int maxDiff = 0;
		for(int i = 2; i < len; i++) {
			int cur = nums[i] - nums[i-1];
			if(cur + pre > maxDiff) maxDiff = cur + pre;
			pre = cur;
		}
		System.out.println(maxDiff);
	}
}

发表于 2022-03-17 19:07:11 回复(0)
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
public class Main{
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int size = Integer.parseInt(br.readLine());
        String height = br.readLine();
        String[] hs = height.split(" ");
        int[] heights = new int[size];
        for(int i = 0; i < heights.length; i++){
            heights[i] = Integer.parseInt(hs[i]);
        }
        System.out.println(handle(heights));
    }
    private static int handle(int[] heights){
        Arrays.sort(heights);
        int max = heights[2] - heights[0];
        for(int i = 2; i < heights.length; i++){
            int gap = heights[i] - heights[i - 2];
            if(gap > max){
                max = gap;
            }
        }
        return max;
    }
}
最高的小孩左边站着第二高的,右边站着第三高的,第二高旁边站着第四高的,如果站着第五高的,那第三高的旁边站着第四高的,不符合差值最小。
所以比较排序后数组的相隔两项差值,找出最大插值即可。
发表于 2021-04-22 02:31:48 回复(0)
(1,3,5....n-2, n, n-1, ...4, 2)每隔一个求差值,取最大值即为答案
发表于 2021-03-08 22:16:57 回复(0)
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Scanner;

//System.out.println("");


public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int d=0;
        int dm=0;
        int n = sc.nextInt();
        int[] array = new int[n];
        for(int i=0; i<n; i++){
            array[i] = sc.nextInt();
        }
        Arrays.sort(array);//身高排序
       for(int i=2;i<n;i+=2){
           d=array[i]-array[i-2];
           if(d<0)d=-d;
           if(d>=dm)dm=d;
            
       }//dm为第一列最大身高差
       for(int i=3;i<n;i+=2){
           d=array[i]-array[i-2];
           if(d<0)d=-d;
           if(d>=dm)dm=d;
           
           
           
       }//dm为第一列和第二列 最大身高差 d=array[0]-array[1]; 
if(d<0)d=-d;
if(d>=dm)dm=d;
d=array[n-1]-array[n-2]; 
if(d<0)d=-d;
if(d>=dm)dm=d;
//dm为第一列、第二列 、列连接处    最大身高差 System.out.println(dm);
        
    }
}
思路:假如h1 h2 h3 h4 h5 h6 ..hn 依次递增(排序)
h1 h2
h3 h4
h5 h6
...
hn-1 hn
这样形成的圈可以保证身高差的最大值最小。 依次计算 身高差 d 取最大值即可

发表于 2018-05-22 22:32:09 回复(0)
import java.util.*;
public class Main{
	public static void main(String[] args) {
		// TODO Auto-generated method stub
       Scanner sc=new Scanner(System.in);
       while(sc.hasNext()){
          int n=sc.nextInt();    //小朋友个数;
          int array[]=new int[n];
          int i=0;
          int maxCount=0;
          ArrayList <Integer> list=new ArrayList <Integer>();
          while(i<n){
        	  array[i]=sc.nextInt();
        	  i++;
          }      
         Arrays.sort(array);
        	for(int j=0;j<array.length;j++){
        		if(j%2==0){
        			list.add(array[j]);
        		}
        	}
        	for(int jj=array.length-1;jj>0;jj--){
        		if(jj%2!=0){
        			list.add(array[jj]);
        		}
        	}
         int arr[]=new int[list.size()];
         Iterator <Integer>it=list.iterator();
         int index=0;
         while(it.hasNext()){
        	 arr[index]=it.next();
        	 index++;
         }
    	maxCount=Math.abs(arr[arr.length-1]-arr[0]);  
    	  for(int k=1;k<arr.length;k++){
               int temp=Math.abs(arr[k]-arr[k-1]);
               maxCount=(maxCount>temp)?maxCount:temp;
          }
    	  System.out.println(maxCount);

       }
       sc.close();
	}
}

发表于 2017-08-18 16:23:56 回复(0)
import  java.util.*;
public class Celebrate61 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
 int n = scanner.nextInt();
 int[] arr = new int[n];
 for (int i = 0; i ; i++) {
arr[i] = scanner.nextInt();
  }
Arrays.sort(arr); //先对数组进行排序
 //用LinkedList来实现队列的先进先出功能  LinkedList queue = new LinkedList();
  Stack stack = new Stack();
 for (int i = 0; i ; i++) {
if((i&1) == 0) {
queue.addLast(arr[i]);
  }
else stack.push(arr[i]);
  }
int size = stack.size();
 for(int i = 0; i ; i++) {
queue.addLast(stack.pop());
  }
int max = Integer.MIN_VALUE;
 for (int i = 1; i ; i++) {
int inter = 0;
 if(i == 0) {
inter = Math.abs(queue.get(n-1) - queue.get(0));
  }
else {
inter = Math.abs(queue.get(i) - queue.get(i-1));
  }
if(max < inter) {
max = inter;
  }
}
System.out.println(max);
  }
}
发表于 2017-08-08 21:23:48 回复(0)
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main(int argc, char const *argv[])
{
	int n;
	cin>>n;
	vector<int> height(n,0);
	for (int i = 0; i < n; ++i)
	{
		cin>>height[i];
	}
	sort(height.begin(),height.end());
	vector<int> res(n,0);
	auto itb=res.begin();
	auto ite=res.end();
	ite--;
	for(int i=0;i<n;i=i+2){
		if(ite==itb){
			*ite=height[i];
			break;
		}
		*itb=height[i];
		*ite=height[i+1];
		ite--;
		itb++;
	}
	int maxh=abs( res[0]- res[1]);
	for(int i=2;i<n;i++){
		maxh=max(maxh,abs( res[i]- res[i-1]));
	}
	cout<<max(maxh,abs( res[0]- res[n-1]));
	return 0;
}

编辑于 2017-08-02 16:19:19 回复(0)
n = int(raw_input())
a = [int(s) fors in raw_input().split()]
 
a.sort()  # 排序

# 找到相隔两个位置的数的差值,这个差值的最大值就是结果
max_v = 0
fori in range(2, n):
    v = a[i] - a[i-2]
    ifv > max_v:
        max_v = v
print max_v
发表于 2017-07-18 19:27:00 回复(0)
1.将数组排序,如:105 103 100 98  2.排好的数组分为两组:arr1{105,100} arr2{98,103}
3.连接成新数组:105,100,98,103
4.求最大的差值
while(n=readline()){
    var arr=readline().split(' ');   
    var allVal=[];
    var arr1=[],arr2=[];
    arr=arr.sort(function(a,b){
        return b-a;
    })
    
    for(var i=0; i<n; i++){
        if(i%2==0) arr1.push(arr[i]);
        else arr2.unshift(arr[i]);
    }
    var res=arr1.concat(arr2);
    
    allVal.push(Math.abs(res[0]-res[n-1]));
    for(var i=1; i<n; i++){
        allVal.push(Math.abs(res[i]-res[i-1]));
    }
    allVal=allVal.sort(function(a,b){
        return b-a;
    })
    print(allVal[0]);
}

发表于 2017-07-14 10:16:10 回复(0)
#排序后以最小值为中心,左边加一个第二小的值,右边家一个第三小的值
#最后计算身高差最大值
def f(n, h_i):
    h_i.sort(reverse = True)
    team = [h_i.pop()]
    n -= 1
    while n > 0:
        team.append(h_i.pop())
        n -= 1
        if n > 0:
            team.insert(0, h_i.pop())
            n -= 1
    ret = []
    for i in range(len(team)-1):
        ret.append(abs(team[i]-team[i+1]))
    return max(ret)
if __name__ == '__main__':
    while 1:
        try:
            n = input()
            h_i = map(int, raw_input().split())
        except:
            break
        print f(n, h_i)

发表于 2017-07-13 15:07:25 回复(0)
/***你们思路都太复杂了,把数组进行排序后,看每个数分别和哪两个数比较。举例 1 3 5 8 9 12 这已经是一个排序好的数组。其中 需要1和3   5 相减得差值并做比较,
                                                  3和1   8,
                                                  5和1   9,
                                                  8和3  12
                                                  9和5  12,
                                                 12和8   9  
去除重复的简化后就只有 1和 3  5,但是5-1绝对比3-1大,所以只需要1 和 5的差值
                                                                                                            3 和 8
                                                                                                            5 和 9
                                                                                                            8 和 12
                                                                                                            9 和 12
因为8和9都要和12相比,所以9和12不需要相比。。由此推广,每个数组去除最后最大的两位数。每个数都与隔位数相减取差值,然后找出差值中的最大值即可 **/
import java.util.Arrays;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int count = sc.nextInt();
int hh[] = new int[count];
for(int i=0; i<count; i++){
hh[i] = sc.nextInt();
}
Arrays.sort(hh);
int max = 0;
for(int i=0; i<count-2; i++){
if(hh[i+2] - hh[i] > max)
max = hh[i+2] - hh[i];
}
System.out.println(max);
}
}

发表于 2017-07-11 10:11:11 回复(0)