首页 > 试题广场 >

拼凑正方形

[编程题]拼凑正方形
  • 热度指数:6972 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
牛牛有4根木棍,长度分别为a,b,c,d。羊羊家提供改变木棍长度的服务,如果牛牛支付一个硬币就可以让一根木棍的长度加一或者减一。牛牛需要用这四根木棍拼凑一个正方形出来,牛牛最少需要支付多少硬币才能让这四根木棍拼凑出正方形。

输入描述:
输入包括一行,四个整数a,b,c,d(1 ≤ a,b,c,d ≤ 10^6), 以空格分割


输出描述:
输出一个整数,表示牛牛最少需要支付的硬币
示例1

输入

4 1 5 4

输出

4

python两行解法

arr = sorted(map(int, input().split()))
print(arr[3] + arr[2] - arr[1] - arr[0])

根据数学推导:

  • 最长的那根木棍和最短的那根,最终要达到相同的长度,那么中间要进行len(max) - len(min)次操作。
  • 第二长的那根木棍和第二短的那根,最终要达到相同的长度,中间要进行len(max2) - len(min2) 次操作。

所以总共要进行len(max) + len(max2) - len(min2)- len(min)次操作

发表于 2019-02-24 19:02:20 回复(7)
#include<iostream> #include<algorithm>
using namespace std;
int main() {     int arr[4];     cin >> arr[0] >> arr[1] >> arr[2] >> arr[3];     sort(arr, arr + 4);     int sum = (arr[3] - arr[0]) + (arr[2] - arr[1]);     cout << sum << endl;     return 0; }

编辑于 2019-01-24 00:19:00 回复(0)

有四个数字,a, b, c, d,从小到大排序,假设边长定为 x,则需要改变的次数为
total =
四个数,能构成五个区域,两端的不考虑,不做解释。

  • x 在 a 和 b 之间时,结果为 ,由于 ,x 取b最小,为

  • x 在 b 和 c 之间时,结果为

  • x 在 c 和 d 之间时,结果为 ,由于 ,x取c最小,为

    import java.io.*;
    import java.util.Arrays;
    public class Main{
    
      public static void main(String[] args) throws Exception {
              BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
              String line = null;
              while((line = br.readLine()) != null){
                  int[] a = new int[4];
                  String[] s = line.trim().split(" ");
                  for(int i=0;i<4;i++){
                      a[i] = Integer.parseInt(s[i]);
                  }
                  Arrays.sort(a);
                  int money = a[2]-a[0]+a[3]-a[1];
                  System.out.println(money);
              }
          }
    }
发表于 2019-07-22 20:43:42 回复(1)
l = list(map(int, input().split()))
l.sort()
m =((l[2])+(l[1]))//2
n = abs(m-l[0])+abs(m-l[1])+abs(m-l[2])+abs(m-l[3])
print(n)

平均绝对误差最小就是中位数
此题正方形边长就是中位数
发表于 2019-05-23 08:55:48 回复(3)
#include<stdio.h>
#include<math.h>
#define min(a,b) a<b?a:b
int main(){
    int a,b,c,d,Min=1e9,i;
    scanf("%d%d%d%d",&a,&b,&c,&d);
    for(i=1;i<=1e6;i++){
        int sum=(int)fabs(a-i)+(int)fabs(b-i)+(int)fabs(c-i)+(int)fabs(d-i);
        Min=min(Min,sum);
    }
    printf("%d",Min);
}

发表于 2017-11-29 13:40:57 回复(4)
arr=list(map(int,input().split()))
pay=[]
for i in range(min(arr),max(arr)+1):
    sum=0
    for j in range(4):
        sum+=abs(arr[j]-i)
    pay.append(sum)
print(min(pay))

发表于 2019-03-22 21:45:33 回复(1)
这道题让我想到了网易的“堆棋子”,可知正方形最后的长度一定是a b c d中的其中一个(证明方法去看“堆棋子”),然后就一个一个试就可以了。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int a, b, c, d, tmp, ans;
    
    while(scanf("%d%d%d%d", &a, &b, &c, &d) == 4)
    {
        ans = abs(a - b) + abs(a - c) + abs(a - d);
        tmp = abs(b - a) + abs(b - c) + abs(b - d);
        ans = (ans < tmp) ? ans : tmp;
        tmp = abs(c - a) + abs(c - b) + abs(c - d);
        ans = (ans < tmp) ? ans : tmp;
        tmp = abs(d - a) + abs(d - b) + abs(d - c);
        ans = (ans < tmp) ? ans : tmp;
        
        printf("%d\n", ans);
    }
    
    return 0;
}

发表于 2019-01-23 12:10:39 回复(2)
先给数组排序,然后第一个元素向第二个元素对其(第二个元素-第一个元素=第一步需要花费的钱),
第二步把最后一个元素向倒数第二个元素对其(倒数第一个元素(最大的数)-倒数第二个元素=第二部需要花费的钱);最后一步把第二个元素向第三个元素对其 (第三个元素-第二个元素=第三步花费的钱) 再把这个钱乘2(因为第一个元素和第二个元素相等,所以一到三需要花费的钱跟二到三一样)  ,再用到的钱加起来
import java.util.*;
public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner cin=new Scanner (System.in);
	    int a[]=new int[4];
	    for(int i=0;i<4;i++) {
	    	a[i]=cin.nextInt();
	    }
	    Arrays.sort(a);
	    int min=0;
	    min=min+(a[1]-a[0])+(a[3]-a[2])+2*(a[2]-a[1]);
	    System.out.print(min);

	}

}


发表于 2019-11-05 18:14:05 回复(0)
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[] arr = new int[4];
        for (int i = 0; i < 4; i++) {
            arr[i] = sc.nextInt();
        }
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < 4; i++) {
            int cur = Math.abs(arr[i] - arr[0]) + Math.abs(arr[i] - arr[1]) + Math.abs(arr[i] - arr[2]) + Math.abs(arr[i] - arr[3]);
            if (cur < min) {
                min = cur;
            }
        }
        System.out.println(min);
    }
}
发表于 2019-06-14 22:25:36 回复(0)
//无脑做法
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int main(int argc, char** argv)
{
    int a, b, c, d, v[4] = { 0 };
    cin >> a >> b >> c >> d;
    v[0] = ab***-a) + abs(c-a) + abs(d-a);
    v[1] = abs(a-b) + abs(c-b) + abs(d-b);
    v[2] = abs(a - c) + abs(c - b) + abs(d - c);
    v[3] = abs(a - d) + abs(d - b) + abs(d - c);
    sort(v, v + 4);
    cout << v[0] << endl;
    system("pause");
}

编辑于 2019-05-22 10:56:37 回复(0)
#include<stdio.h>
int main()
{
    int i,j,t,a[4];
    for(i=0;i<4;i++)
      scanf("%d",&a[i]);
    for(i=0;i<3;i++)
    {
        for(j=0;j<3-i;j++)
        {
            if(a[j]>a[j+1])
            {
                t=a[j];a[j]=a[j+1];a[j+1]=t;
            }
        }
    }
    printf("%d",a[3]+a[2]-a[1]-a[0]);
    return 0;
}
就是用最长的减去最短的,再用第二长的减去第二短的,两者相加就是最少用的钱
发表于 2019-05-06 15:52:21 回复(0)
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
    int a[4];
    for (int i = 0; i < 4; i++)
        cin >> a[i];
    sort(a, a + 4);
    cout << (a[3] - a[0]) + (a[2] - a[1])<<endl;
    system("pause");
    return 0;
}

发表于 2019-04-22 19:35:44 回复(0)
lst=list(map(int, input().split()))
print(min([sum([abs(j-i) for j in lst]) for i in range(min(lst),max(lst)+1)]))
同样的Python两行代码,不用sorted函数,且这个做法对输入列表的长度无要求(可以是正五边形、正六边形等等),当然思路和高赞是一致的。
拆分出来的代码就是:
lst=list(map(int, input().split()))
a1=min(lst)
a2=max(lst)
cs=[]
for i in range(a1,a2+1):
    k=0 #完全可以用sum加abs加列表推导式的,不想用太多高级函数
    #k=sum([abs(j-i) for j in lst])
    for j in lst:
        #k=k+abs(j-i)
        m=j-i
        if m<0:
            k-=m
        else:
            k+=m
    cs.append(k)
print(min(cs))

发表于 2019-03-20 14:10:56 回复(1)
数学题

l = sorted(list(map(int, input().split())))
print(l[3] - l[0] + l[2] - l[1])

发表于 2019-03-18 17:40:35 回复(0)
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<vector>
#include<math.h>
using namespace std;
int main(){
    //木棍拼凑正方形,四个木棍长度相等
    int a, b, c, d;
    cin >> a >> b >> c >> d;
    //最后的正方形的边长必为初始给的四个数之一
    int m1, m2, m3, m4;
    m1 = abs(b - a) + abs(c - a) + abs(d - a);
    m2 = abs(a - b) + abs(c - b) + abs(d - b);
    m3 = abs(a - c) + abs(b - c) + abs(d - c);
    m4 = abs(a - d) + abs(b - d) + abs(c - d);
    cout << min(min(m1, m2),min(m3, m4)) << endl;
    return 0;
}
发表于 2019-03-02 16:08:50 回复(0)
#include <bits/stdc++.h>

using namespace std;

int main()
{     int a[4];     while(cin>>a[0]>>a[1]>>a[2]>>a[3]){         int s=0;         sort(a,a+4);         for(int i=0;i<4;i++)             s += abs(a[i]-a[2]);         cout<<s<<endl;     }     return 0;
}

发表于 2019-02-14 01:47:35 回复(0)
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[] lens = new int[4];
        for (int i=0; i!=4; i++) {
            lens[i] = sc.nextInt();
        }
        Arrays.sort(lens);
        int ans = 0;
        for (int i=0; i!=4; i++) {
            ans += Math.abs(lens[i] - lens[2]);
        }
        System.out.println(ans);
    }
}
发表于 2019-01-20 20:00:04 回复(0)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

/**
 * @author wylu
 */
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] strs = br.readLine().split(" ");
        int[] a = new int[strs.length];
        for (int i = 0; i < strs.length; i++) a[i] = Integer.parseInt(strs[i]);
        Arrays.sort(a);
        System.out.println((a[3] - a[0]) + (a[2] - a[1]));
    }
}

编辑于 2019-01-24 10:50:50 回复(0)
//JS***
var str = readline();
var arr = str.split(" ");
arr.sort(function(a,b){
    return b-a;
})
var num = [];
for(var i =0 ;i<arr.length;i++){
    num[i] = 0;
    for(var j = 0 ; j< arr.length ;j++){
        var gap = (parseInt(arr[i])-parseInt(arr[j]));
        num[i] +=parseInt(Math.abs(gap));
    }
}
print(Math.min.apply(Math,num));

发表于 2018-08-16 14:27:37 回复(0)
let arr = readline().split(' ').map(item => parseInt(item));
let allSequence = []; //所有结果
// 思路:边长为四个数的其中一个,然后将修改后的长度填入数组,找出最小的那个
function fn(x,arr) {
    let sum = Math.abs(x-arr[0]) + Math.abs(x-arr[1]) + Math.abs(x-arr[2]) + Math.abs(x-arr[3])
    allSequence.push(sum);
}
arr.forEach((item, index, arr) => fn(item, arr))
function findMin(a, b) {
    return a - b;
}
allSequence.sort(findMin);
console.log(allSequence[0]);
//谢谢 元气の悟空 的解析 提供了思路
发表于 2018-04-23 13:54:06 回复(0)