码迷,mamicode.com
首页 > 编程语言 > 详细

Hoj1412 求两个集合的和{A} + {B}——java实现最优解的辛酸路

时间:2015-01-25 15:21:04      阅读:263      评论:0      收藏:0      [点我收藏+]

标签:hoj   集合求和   java实现   最优解   数学   

写在前面


寒假闲来无事,突发奇想,想A俩题玩玩,许久没A过题了,想想那手指暴力敲击键盘的感觉就是一阵酸爽啊。


做的前几个题还挺顺溜,大概半个小时一个题吧,A了三四个,谁知道到第五个卡这了。


一个看上去很简单的题楞是卡了我俩小时,不过结果还算不错。


打破了个记录,竟然一不小心成为了这个题的最优解。。。。。。。



详细描述点击此处参见原题



大致就是:

给你两个集合,要求{A} + {B}.

注:同一个集合中不会有两个相同的元素.

辛酸分析路



(1)用Java自带的工具


因为本身是玩Java的,首先想到的肯定是用Java自带的set集合,申请一个set直接装两个集合A,B的元素(自动去重复了就), 然后再对其进行排序,就OK了

import java.util.HashSet;
import java.util.Scanner;

/**
 * @author_Stone6762
 */
public class Main {

	/**
	 * @Title_strArr2Str
	 * @Describe_将一个字符串数组变成一个字符串_两个字符串中间穿插上指定的字符
	 * @Author_Stone6762
	 * @param arr字符串数组
	 * @param signs中间想要插入的字符
	 * @return
	 */
	public static String arr2String( Object[] arr, String signs) {
		String aim = "";
		for (int i = 0; i < arr.length; i++) {
			if (i == 0) {
				aim += arr[i].toString();
				continue;
			}
			aim += signs + arr[i];
		}

		return aim;
	}
	private static void chooseSort(Integer[] arr) {
		for (int i = 0; i < arr.length - 1; i++) {
			int min = i;
			for (int j = i + 1; j < arr.length; j++) {
				if (arr[j] < arr[min]) {
					min = j;
				}
			}
			int temp = arr[i];
			arr[i] = arr[min];
			arr[min] = temp;
		}
	}
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		while (scan.hasNext()) {
			int n=scan.nextInt();
			int m=scan.nextInt();
			HashSet<Integer>set=new HashSet<Integer>();
			for (int i = 0; i <m+n; i++) {
				set.add(scan.nextInt());				
			}
			Integer []arr=set.toArray(new Integer[0]);
			chooseSort(arr);
			System.out.println(arr2String(arr, " "));
		}
	}

}

结果果然“不负众望”,超时了,呵呵,Java自带的工具果然不让用啊,那好吧,继续分析



(2)笨方法硬上

集合不让用集合存储,那只能用数组了,直接申请一个大数组(容量为A+B),先装集合A,然后装集合B,


装集合B的每一个元素的时候    都对集合A进行遍历如果已经有了就不要了,如果没有就装进去


麻烦点就麻烦点吧,肯定好使

import java.util.Scanner;

/**
 * @author_Stone6762
 */
public class Main {

	private static String intArr2String(int[] arr, int k) {
		String aim = "";
		for (int i = 0; i < k; i++) {
			if (i == 0) {
				aim += arr[i];
				continue;
			}
			aim += " " + arr[i];
		}

		return aim;
	}

	private static void chooseSort(int[] arr) {
		for (int i = 0; i < arr.length - 1; i++) {
			int min = i;
			for (int j = i + 1; j < arr.length; j++) {
				if (arr[j] < arr[min]) {
					min = j;
				}
			}
			int temp = arr[i];
			arr[i] = arr[min];
			arr[min] = temp;
		}
	}

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		while (scan.hasNext()) {
			int n = scan.nextInt();
			int m = scan.nextInt();
			int arr[] = new int[m + n];
			for (int i = 0; i < n; i++) {
				arr[i] = scan.nextInt();
			}
			boolean flag = true;
			int k = n;
			for (int i = n; i < arr.length; i++) {
				int t = scan.nextInt();
				flag = true;
				for (int j = 0; j < k; j++) {
					if (arr[j] == t) {
						flag = false;
						break;
					}
				}
				if (flag) {
					arr[k] = t;
					k++;
				}
			}
			for (int i = k; i < arr.length; i++) {
				arr[k] = Integer.MAX_VALUE;
			}
			chooseSort(arr);
			System.out.println(intArr2String(arr, k));
		}
	}
}

结果还是超时,好吧,双重循环超时也应该,那再来


(3)变形再来


申请两个数组,分别装集合A和集合B中的元素,然后分别对集合A和集合B进行排序


然后从集合A和集合B中选出当前最小的元素MinA,MinB,进行比较


①如果二者相等,输出任意一个即可,然后从两个集合中选取第二小的进行比较

②如果MinA>MinB,那么直接输出MinB,然后从B中选出一个第二小的进行比较,反正亦然

③知道一个数组为空,然后输出另一个数组的全部元素


这次应该行了吧。。。。。。

import java.util.Scanner;

/**
 * @author_Stone6762
 */
public class Main {

	private static void chooseSort(int[] arr) {
		for (int i = 0; i < arr.length - 1; i++) {
			int min = i;
			for (int j = i + 1; j < arr.length; j++) {
				if (arr[j] < arr[min]) {
					min = j;
				}
			}
			int temp = arr[i];
			arr[i] = arr[min];
			arr[min] = temp;
		}
	}

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		while (scan.hasNext()) {
			int n = scan.nextInt();
			int m = scan.nextInt();
			int arrA[] = new int[n];
			int arrB[] = new int[m];
			for (int i = 0; i < n; i++) {
				arrA[i] = scan.nextInt();
			}
			for (int i = 0; i < m; i++) {
				arrB[i] = scan.nextInt();
			}
			chooseSort(arrA);
			chooseSort(arrB);

			int i = 0, j = 0;
			while (i < n && j < m) {
				int a = arrA[i];
				int b = arrB[j];
				if (a == b) {
					System.out.print(b + " ");
					j++;
					i++;
				} else if (b > a) {
					System.out.print(a + " ");
					i++;
				} else {
					System.out.print(b + " ");
					j++;
				}
				if (i >= n) {
					while (j < m - 1) {
						System.out.print(arrB[j] + " ");
						j++;
					}
					System.out.print(arrB[j]);
					break;
				}
				if (j >= m) {
					while (i < n - 1) {
						System.out.print(arrA[i] + " ");
						i++;
					}
					System.out.print(arrA[i]);
					break;
				}
			}
			System.out.println();

		}
	}
}


结果直接是错误,也是醉了,也是废了,为毛啊。。。。。


打破重来吧, 删除全部代码推倒重新分析


(4)换种思路推倒重建


做到此刻,慢慢开始冷静了,没那么玩过啊,这都用了将近一个小时了。。。。。。。。


最后分析的结果:


直接硬来,申请一个数组装俩集合中的元素,然后什么都不管直接排序。


如果两个元素相同,那么肯定会挨着,在输出的时候进行判断,相等的只输出一个


import java.util.Arrays;
import java.util.Scanner;
/**
 *@authorStone6762
 */
public class Main {

    public static void main(String[] args) {
        //Scanner scan = new Scanner(System.in);
        while (scan.hasNext()) {
            int n = scan.nextInt();
            int m = scan.nextInt();
          //  int arr[] = new int[n + m];
            for (int i = 0; i <arr.length; i++) {
                arr[i] = scan.nextInt();
            }
          //  Arrays.sort(arr);
            System.out.print(arr[0]);
            for (int i = 1; i < arr.length; i++) {
            //    if(arr[i]!=arr[i-1]){
                    System.out.print(" "+arr[i]);
                }
            }
            System.out.println();
        }
    }
}


结果是A了,终于A了,不过花了一个半小时A了这么个大水题总感觉亏了,实在是亏了。。。。反正已经这样了,再优化一下吧


(5)再次修改


仔细再看了看

时间上能优化的地方也就只剩下输入和输出的地方了,其他的也确实一时半会想不到了

空间上也就是能再少用一个半个变量

最后

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;

/**
 * @author_Stone6762
 */
public class Main {

    public static void main(String[] args) throws IOException {
        //StreamTokenizer in = new StreamTokenizer(new InputStreamReader(
                System.in));
        //PrintWriter out = new PrintWriter(System.out);
        while (in.nextToken() != StreamTokenizer.TT_EOF) {
            int n = (int) in.nval;
          //  in.nextToken();
            int m = (int) in.nval + n;
            int arr[] = new int[m];
            for (int i = 0; i < m; i++) {
            //    in.nextToken();
                arr[i] = (int) in.nval;
            }
            //Arrays.sort(arr);
           // out.print(arr[0]);
            //out.flush();
            for (int i = 1; i < m; i++) {
                if (arr[i] != arr[i - 1]) {
               //     out.print(" " + arr[i]);
             //       out.flush();
                }
            }
            out.println();
            out.flush();
        }
    }

}


结果没想到竟然是一下成了榜单第一,真是不知道该哭还是该笑了。。。。。。。。。


Hoj1412 求两个集合的和{A} + {B}——java实现最优解的辛酸路

标签:hoj   集合求和   java实现   最优解   数学   

原文地址:http://blog.csdn.net/u011446177/article/details/43113865

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!