寒假闲来无事,突发奇想,想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实现最优解的辛酸路
原文地址:http://blog.csdn.net/u011446177/article/details/43113865