2020年09月 HNUCM-OJ算法分析与设计作业7
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了2020年09月 HNUCM-OJ算法分析与设计作业7,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含8251字,纯文字阅读大概需要12分钟。
内容图文
@ZHANGQIANYI2020
HNUCM-OJ 归并排序,大整数乘法,第k小元素问题,第k大元素问题,前m大数,找中位数
问题 A: 归并排序
(时间限制: 1 Sec 内存限制: 256 MB)
题目描述:
编写一个程序,使用分治策略实现二路归并排序(升序)。
输入:
多组输入,每组第一个数字为数组长度,然后输入一个一维整型数组。
输出:
输出排序之后(升序)的一维整型数组,每组输出占一行。
样例输入:
6 1 8 6 5 3 4
5 12 42 2 5 8
样例输出:
1 3 4 5 6 8
2 5 8 12 42
参考答案:
import java.util.Scanner;
public class Main {
public static void sort(int []arr){
int []temp = new int[arr.length];
sort(arr,0,arr.length-1,temp);
}
private static void sort(int[] arr,int left,int right,int []temp){
if(left<right){
int mid = (left+right)/2;
sort(arr,left,mid,temp);
sort(arr,mid+1,right,temp);
merge(arr,left,mid,right,temp);
}
}
private static void merge(int[] arr,int left,int mid,int right,int[] temp){
int i = left;
int j = mid+1;
int t = 0;
while (i<=mid && j<=right){
if(arr[i]<=arr[j]){
temp[t++] = arr[i++];
}else {
temp[t++] = arr[j++];
}
}
if(i>mid){
for(int q=j;q<=right;q++)
temp[t++] = arr[q];
}else{
for(int q=i;q<=mid;q++)
temp[t++] = arr[q];
}
t = 0;
while(left <= right){
arr[left++] = temp[t++];
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()) {
int n=sc.nextInt();
int a[]=new int[n];
for(int i=0;i<n;i++) {
a[i]=sc.nextInt();
}
sort(a);
for(int i=0;i<n;i++) {
System.out.print(a[i]+" ");
}
}
}
}
问题 B: 大整数乘法
(时间限制: 1 Sec 内存限制: 128 MB)
题目描述:
使用分治算法实现两个大整数相乘。
输入:
两个十进制大整数,满足每一个整数长度为2^n且两个大整数的长度相等。(多组数据)
输出:
两个大整数的乘积。
样例输入:
1234 5678
样例输出:
7006652
参考答案:
import java.util.Scanner;
public class Main {
public static long zhengshucheng(long x,long y,int n) {
int signx=(x<0?-1:1);
int signy=(y<0?-1:1);
int sign=signx*signy;
x=Math.abs(x);
y=Math.abs(y);
if(x==0||y==0) {
return 0;
}else if(n==1) {
return sign*x*y;
}else {
long A=(long) (x/Math.pow(10, n/2));
long B=(long) (x%Math.pow(10, n/2));
long C=(long) (y/Math.pow(10, n/2));
long D=(long) (y%Math.pow(10, n/2));
long AC=zhengshucheng(A,C,n/2);
long BD=zhengshucheng(B,D,n/2);
long ABCD=zhengshucheng((A-B),(D-C),n/2)+AC+BD;
return (long) (sign*(AC*Math.pow(2,n)+ABCD*Math.pow(2, n/2)+BD));
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()) {
long x=sc.nextInt();
long y=sc.nextInt();
long z=x*y;
System.out.println(z);
}
}
}
问题 C: 第k小元素问题
(时间限制: 1 Sec 内存限制: 128 MB)
题目描述:
输入一个整数数组,请求出该数组的第k小元素。要求时间复杂度为O(n)。
输入:
每组输入包括两行,第一行为一个整数数组,两个数字之间用空格隔开;第二行为k值。数组中元素个数小于10^9。
输出:
输出第k小元素的值。
样例输入:
2 5 6 1 8 7 9
2
样例输出:
2
参考答案:
import java.util.Random;
import java.util.Scanner;
public class Main {
public static int quickSelect(int[] arr, int start, int end, int k) {
if (start > end)
return -1;
int p = partition(arr, start, end);
if (k == p) {
return p;
} else if (k < p) {
return quickSelect(arr,start, p-1,k);
} else {
return quickSelect(arr,p+1,end,k);
}
}
public static int partition(int[] arr, int start, int end) {
if (start == end)
return start;
int p = getRandom(start, end);
swap(arr, p, start);
p = start;
int p1 = start;
int p2;
for (p2 = p + 1; p2 <= end; p2++) {
if (arr[p2] < arr[p]) {
p1++;
swap(arr, p1, p2);
}
}
swap(arr, p1, p);
p = p1;
return p;
}
public static int getRandom(int start, int end) {
Random random = new Random();
int temp = random.nextInt(end - start + 1) + start;
return temp;
}
public static void swap(int[] arr, int a, int b) {
int temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
public static void printArray(int[] arr) {
for(int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
if(i < arr.length -1) {
System.out.print(" ");
}
}
System.out.println();
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String s1 = sc.nextLine();
String s2 = sc.nextLine();
int num = Integer.parseInt(s2);
String[] arrString = s1.split(" ");
int[] arrNum = new int[arrString.length];
for (int i = 0; i < arrString.length; i++) {
arrNum[i] = Integer.parseInt(arrString[i]);
}
arrString = null;
int result = quickSelect(arrNum, 0, arrNum.length - 1, num - 1);
if (result != -1) {
System.out.println(arrNum[result]);
}
}
sc.close();
}
}
问题 D: 第k大元素问题
(时间限制: 1 Sec 内存限制: 128MB)
题目描述:
输入n个整数和一个正整数k(1<=k<=n),输出这些整数从大到小排序后的第k个。(要求时间复杂度为O(n),需使用随机化分区) 。
输入:
多组数据输入,每组第一个数字为数组的长度n, 然后接下输入n个整数,最后输入整数k(1<=k<=n)。
输出:
输出数组降序排序后的第k个整数。
样例输入:
5 1 5 2 4 3 3
6 1 2 3 4 5 6 1
样例输出:
3
6
参考答案:
import java.util.Random;
import java.util.Scanner;
public class Main {
public static int Ran(int p,int r) {
Random ran=new Random();
int i=ran.nextInt(r-p)+p;
return i;
}
private static int partition(int[] a, int p, int r) {
int x=a[r];
int i=p-1;
int temp=0;
for(int j=p;j<=r-1;j++) {
if(a[j]>=x) {
i=i+1;
temp=a[i];
a[i]=a[j];
a[j]=temp;
temp=0;
}
}
temp=a[i+1];
a[i+1]=a[r];
a[r]=temp;
return i+1;
}
private static int ranpartition(int[] a, int p, int r) {
// TODO Auto-generated method stub
int q=Ran(p,r);
int temp=a[q];
a[q]=a[r];
a[r]=temp;
return partition(a,p,r);
}
public static int ranselect(int[] a,int p,int r,int k) {
if(p==r)
return a[p];
int i=ranpartition(a,p,r);
int j=i-p+1;
if(k<=j) {
return ranselect(a,p,i,k);
}else {
return ranselect(a,i+1,r,k-j);
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()) {
int n=sc.nextInt();
int a[]=new int[n];
for(int i=0;i<n;i++) {
a[i]=sc.nextInt();
}
int k=sc.nextInt();
System.out.println(ranselect(a,0,n-1,k));
}
}
}
问题 E: 前m大数
(时间限制: 1 Sec 内存限制: 33MB)
题目描述:
给你n个整数,请按从大到小的顺序输出其中前m大的数。
输入:
每组测试数据有两行,第一行有两个数n,m(0<n,m<1000000),第二行包含n个各不相同,且都处于区间[-500000,500000]的整数。
输出:
对每组测试数据按从大到小的顺序输出前m大的数。
样例输入:
5 3
3 -35 92 213 -644
样例输出:
213 92 3
参考答案:
import java.util.Random;
import java.util.Scanner;
public class Main {
public static int Ran(int p,int r) {
Random ran=new Random();
int i=ran.nextInt(r-p)+p;
return i;
}
private static int partition(int[] a, int p, int r) {
int x=a[r];
int i=p-1;
int temp=0;
for(int j=p;j<=r-1;j++) {
if(a[j]>=x) {
i=i+1;
temp=a[i];
a[i]=a[j];
a[j]=temp;
temp=0;
}
}
temp=a[i+1];
a[i+1]=a[r];
a[r]=temp;
return i+1;
}
private static int ranpartition(int[] a, int p, int r) {
// TODO Auto-generated method stub
int q=Ran(p,r);
int temp=a[q];
a[q]=a[r];
a[r]=temp;
return partition(a,p,r);
}
public static void ranqsort(int a[],int p,int r) {
if(p<r) {
int q=ranpartition(a,p,r);
ranqsort(a,p,q-1);
ranqsort(a,q+1,r);
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()) {
int n=sc.nextInt();
int m=sc.nextInt();
int a[]=new int[n];
for(int i=0;i<n;i++) {
a[i]=sc.nextInt();
}
ranqsort(a,0,n-1);
for(int i=0;i<m;i++) {
System.out.print(a[i]+" ");
}
System.out.println();
}
}
}
问题 F: 找中位数
(时间限制: 1 Sec 内存限制: 128MB)
题目描述:
请设计一个算法,不排序,快速计算出一个无序数列的中位数。 时间复杂度要求为O(n)。
如果有奇数个元素,中位数则是数组排序后最中间的那个数字。
如果是偶数个元素,中位数则是数组排序后最中间两个元素的平均值。
输入:
有多组输入,每组输入的第一行为n(1<=n<=1e5),表示该数列的元素个数。
第二行为n个整数组成的无序数列
输出:
每组样例输出一行,表示该无序数列的中位数。
若为偶数,请保留三位小数
若为奇数,直接输出
样例输入:
5
5 3 2 1 4
样例输出:
3
参考答案:
import java.text.DecimalFormat;
import java.util.Scanner;
public class Main {
public static int partition(int a[],int p,int q) {
int x=a[p];
int i=p,j;
for(j=p+1;j<=q;j++) {
if(a[j]<x) {
i++;
swap(a,i,j);
}
}
swap(a,p,i);
return i;
}
public static void swap(int a[],int p,int q) {
int v;
v=a[p];
a[p]=a[q];
a[q]=v;
}
public static void getMid(int a[],int p,int q) {
int mid=(p+q)/2;
while(true) {
int pos=partition(a,p,q);
if(pos==mid)break;
else if(pos>mid) {q=pos-1;}
else {p=pos+1;}
}
if(a.length%2!=0) {
System.out.println(a[mid]);
}
else {
double MID=1.0*(a[mid]+a[mid+1])/2;
System.out.println(String.format("%.3f", MID));
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()) {
int n=sc.nextInt();
int a[]=new int[n];
for(int i=0;i<a.length;i++) {
a[i]=sc.nextInt();
}
getMid(a,0,a.length-1);
}
}
}
内容总结
以上是互联网集市为您收集整理的2020年09月 HNUCM-OJ算法分析与设计作业7全部内容,希望文章能够帮你解决2020年09月 HNUCM-OJ算法分析与设计作业7所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。