欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

在路上遇见的一些算法问题

程序员文章站 2022-07-14 09:16:23
...

在每天码代码的过程中,有时候会遇见一些比较经典的算法问题。我想总结一下最近遇见的一下算法。

问题:
有一个桶,里面有白球和黑球各100个,规则如下:
1.每次随机从桶中取出两个球
2.如果是两个同色的球,就再放入一个黑球
3.如果是两个异色的球,就再放入一个白球
问:最后桶中只剩下一个黑球的概率是多少?(白球数不管)
答:
我们可一个用一个set(黑球数量,白球数量)来表示桶中的黑球和白球的个数。从桶中取出球后,只可能是下列三种操作:
1.取出的是两个黑球,则放回一个黑球:(-2, 0) + (1, 0) = (-1, 0)
2.取出的是两个白球,则放回一个黑球:(0, -2) + (1, 0) = (1, -2)
3.取出的是一黑一白,则放回一个白球:(-1, -1) + (0, 1) = (-1, 0)
根据上面的规则,我们可以发现:白球的数量变化情况只能是不变或者-2,也就是说,如果是100个白球,白球永远不可能是1个的情况,那么问题的解法就很简单了,就是只剩下黑球的概率为100%。

问:给你一个自然数N,求【6,N】之内所有素数中两两之和为偶数的那些偶数。
用哥德巴赫猜想(欧拉版):任一大于2的偶数都可写成两个质数之和
答:故只需列出所有偶数即可。[6,N]的素数之和最小偶数为14(允许相同素数的情况下),最大偶数为最大素数的2倍。

问:有一种毒药,猪喝了15分钟内会死亡(假设猪喝水不花费时间,而且不是定时死亡)。现在我们有1000桶水,需要用猪去测出哪桶水有毒,需要几头猪?
答:使用数列(五维空间)方法,5头。

问:排序方法有哪些?

答:

1.冒泡

void BubbleSort(int arr[],int count)
 {
     int temp=0;
     bool swapped=false;
     for(int i=1;i<count;i++)
     {
         swapped=false;
         for(int j=count-1;j>=i;j--)
         {
             if(arr[j-1]>arr[j])
             {
                 temp=arr[j-1];
                 arr[j-1]=arr[j];
                 arr[j]=temp;

            }
             swapped=true;
         }

        if(!swapped)//本趟排序未发生交换,提前终止算法
            return;
     }
 }

2.二分查找

int BinSearch(int *arr, int n , int key)
 {
     int low = 0;
     int high = n-1;
     int mid;              
     if(arr[low] == key)
     {
         return 0;
     }

    while(low <= high)
     { 
         mid = low + ((high - low)/2);
         if(arr[mid] == key)
         {
             return mid;
         }

        if(arr[mid] > key)
             high = mid - 1; 
         else
             low = mid + 1;
     }
     return -1;
 }

3.快排

#include <stdio.h>
 int a[100] = { 1, 2, 8, 7, 9, 5, 6, 4, 3, 66, 77, 33, 22, 11 };
  
 /* 输出数组前n各元素*/
void prt(int n) {
     int i;
     for (i = 0; i < n; i++) {
         printf("%d\t", a[i]);
     }
     printf("\n");
 }
  
 /* 数据交换*/
void swap(int *a, int *b)
 {
     int tmp;
     tmp = *a; *a = *b; *b = tmp;
 }
  
 void quick_sort(int a[], int left, int right)
 {
     int i = left + 1, j = right;
     int  key = a[left];
  
     if (left >= right) return;
  
     /* 从i++和j--两个方向搜索不满足条件的值并交换 *
      * 条件为:i++方向小于key,j--方向大于key      */
     while (1) {
        while (a[j] > key) j--;
        while (a[i] < key&&i<j) i++;
        if(i >= j) break;
        swap(&a[i],&a[j]);
        if(a[i]==key)j--;
        else  i++;
     }
  
     /* 关键数据放到‘中间’*/
     swap(&a[left],&a[j]);
  
     if(left  < i - 1)   quick_sort(a, left, i - 1);
     if(j + 1 < right)  quick_sort(a, j + 1 , right);
  
 }
  
 int main(void) {
  
     /* 排序与输出*/
     quick_sort(a, 0, 13);
     prt(14);
  
     return 0;
 }

问:101个硬币中有一个假币,有一个无砝码的天平,称两次,判断假币比真币重还是轻。
答:
方案1:把101个硬币平均分成三份,分别是:33,33,35,把两 堆33个放在天平上称。
1、如果平衡,说明这66个都是真的。然后从这两堆共66个中取出35个,与第三堆的35个分别放在天平的左右盘中称,这样,第三堆所在的天平的那一端的轻重就是假币的轻重情况。
2、如果两 个33放在天平上不平衡,说明第三堆的35个是真的。取下轻的一端的33个,从第三堆中取33个放在上面,如果平衡,说明取下的一堆中有假币,假币比真的轻。如果不平衡,只有一种结果,第三堆与取下的一堆一样,都比那一堆轻,说明假的比真的重。
方案2:将硬币按A组(50)、B组(50)、C组(1)分组,先比较A、B两组:

1>.若A=B,则C为假币,再用A或B中任一个与C比,C重则假币重,C轻则真币重

2>.若A!=B,则A或B中含假币,将A组一分为二:A1(25)、A2(25),比较A1、A2:

   <1>.若A1=A2,则A为真币,故:A>B => 真币重;A<B => 假币重

   <2>.若A1!=A2,则A含假币,故:A<B => 真币重;A>B => 假币重

问:有一把手枪(无线子弹),当第一个人拿到手枪会打死旁边的人,然后将手枪传下去。1000个人拿着手枪围着圈坐在一起,请问最后存活的是第几个人?
答:第977个 【n-2^j】* 2+1;
java实现

public class NewtonMethod {

	public static void main(String[] args) {

		Scanner scanner=new Scanner(System.in);
		System.out.println("请输入参与人数");
		String scan=scanner.next();
		int a=Integer.parseInt(scan);
		NewtonMethod  newtonMethod = new NewtonMethod();
		//int x = newtonMethod.sqrt(2);
		int o = newtonMethod.HA(a);
		System.out.println("幸运人数是第"+o+"位");
		//System.out.print(x);
	}

	public int HA(int n)
	{
		int k=0;
		for( double i=0;Math.pow(2,i)<n;i++)
		{
			double sum=(n-Math.pow(2,i))*2+1;
			k = (int)sum;
		}
		
		return k;
		
	}}

问:从最多10个整数的集合中,分成两组(不需平均分组,可以一组1个、另一组9个),要求只要两组的总和差值最小,还有就是集合里的数量可奇可偶。
答:

public class RandomlyAssigned {

	public static void main(String[] args) {
                // 从大到小排好序的数组
                int arr[]={100,91,81,77};
		List<Integer> sum1=new ArrayList<Integer>();
		List<Integer> sum2=new ArrayList<Integer>();
		int a=0;
		int b=0;
		for(int i=0;i<arr.length;i++){
			if(a<=b){
				sum1.add(arr[i]);
				a+=arr[i];
			}else{
				sum2.add(arr[i]);
				b+=arr[i];
			}
		}
		System.out.println("A:" + sum1 + ", B: " + sum2 + ", 差值:" + Math.abs(a - b));
	}
}

升级版

package com.Test.method;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

/**
 * @author Sakura
 * @function 分组选出差值最小的两组
 * @date 2018-12-7
 * @modify date ,modify author,modify cause
 *
 */
public class RandomlyAssigned {

	public static void main(String[] args) {
		System.out.print("请输入您要分配的数组长度和数组 如:3组   分别是 1 2 3\n");
		Scanner scanner = new Scanner(System.in);
		while (scanner.hasNext()) {
			int m = scanner.nextInt();
			int[] arr = new int[m];
			for (int i = 0; i < m; i++) {
				arr[i] = scanner.nextInt();
			}
			System.out.print("您输入的数组是:\n" + Arrays.toString(arr) + "\n");
			RandomlyAssigned RanASS = new RandomlyAssigned();
			RanASS.BubbleSort(arr, m);
			RanASS.Random(arr);
		}
	}

	public void BubbleSort(int arr[], int count) {
		int temp = 0;
		boolean swapped = false;
		for (int i = 1; i < count; i++) {
			swapped = false;
			for (int j = count - 1; j >= i; j--) {
				if (arr[j - 1] < arr[j]) {
					temp = arr[j - 1];
					arr[j - 1] = arr[j];
					arr[j] = temp;

				}
				swapped = true;
			}
		}
		System.out.print("由大到小排列后:\n" + Arrays.toString(arr) + "\n");
	}

	public void Random(int arr[]) {
		int sum1 = 0;
		int sum2 = 0;
		List<Integer> group1 = new ArrayList<Integer>();
		List<Integer> group2 = new ArrayList<Integer>();
		for (int i = 0; i < arr.length; i++) {
			if (sum1 <= sum2) {
				group1.add(arr[i]);
				sum1 += arr[i];
			} else {
				group2.add(arr[i]);
				sum2 += arr[i];
			}
		}
		System.out.println("分组后为:\n" + "A:" + group1 + ", B: " + group2
				+ "\n 差值:" + Math.abs(sum1 - sum2));

	}
}
相关标签: 算法 逻辑思维