1420: 数组合并
题目描述
编写一个程序,将两个有序数组合并成一个更大的有序数组,要求时间复杂度为O(n)。
输入
多组数据输入,每组输入包括两行,每行第一个数字为数组长度n,然后输入n个有序整数。
输出
输出合并后的数组(升序),每组输出用一个空行隔开。
样例输入 Copy
3 1 3 5 3 2 4 6 2 1 2 4 3 4 5 6
样例输出 Copy
1 2 3 4 5 6 1 2 3 4 5 6
import java.util.Scanner;
public class Main{
public static void f(int[] num1,int m,int[] num2,int n){
int p1=m-1;
int p2=n-1;
int p=m+n-1;
int c[]=new int[num1.length+num2.length];
while((p1>=0)&&(p2>=0))
c[p--]=(num1[p1]<num2[p2])?num2[p2--]:num1[p1--];
while((p1>=0)&&(p2==-1))
c[p--]=num1[p1--];
while((p2>=0)&&(p1==-1))
c[p--]=num2[p2--];
for(int i=0;i<c.length;i++){
System.out.printf("%d ",c[i]);
}
System.out.println();
System.out.println();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan=new Scanner(System.in);
while(scan.hasNext()){
int n=scan.nextInt();
int a[]=new int[n];
for(int i=0;i<n;i++){
a[i]=scan.nextInt();
}
int m=scan.nextInt();
int b[]=new int[m];
for(int i=0;i<m;i++){
b[i]=scan.nextInt();
}
f(a,n,b,m);
}
}
}
1421: 归并排序
题目描述
编写一个程序,使用分治策略实现二路归并排序(升序)。
输入
多组输入,每组第一个数字为数组长度,然后输入一个一维整型数组。
输出
输出排序之后(升序)的一维整型数组,每组输出占一行。
样例输入 Copy
6 1 8 6 5 3 4 5 12 42 2 5 8
样例输出 Copy
1 3 4 5 6 8 2 5 8 12 42
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
void merge(int arr[],int start1,int end1,int start2,int end2){
int n1=end1-start1+1;
int n2=end2-start2+1;
int arr_left[n1],arr_right[n2];
for(int i=0;i<n1;i++) arr_left[i]=arr[start1+i];
for(int i=0;i<n2;i++) arr_right[i]=arr[start2+i];
int left=0,right=0;
int p=start1;
while(left<n1 && right<n2){
if(arr_left[left]<arr_right[right]){
arr[p]=arr_left[left];
left++;
}else{
arr[p]=arr_right[right];
right++;
}
p++;
}
while(left<n1){
arr[p]=arr_left[left];
left++;
p++;
}
while(right<n2){
arr[p]=arr_right[right];
right++;
p++;
}
}
void mergesort(int arr[],int start,int end){
if(start<end){
int mid=start+(end-start)/2;
mergesort(arr,start,mid);
mergesort(arr,mid+1,end);
merge(arr,start,mid,mid+1,end);}
}
int main(){
int n;
while(cin >> n){
int arr[n];
for(int i=0;i<n;i++)
cin >> arr[i];
mergesort(arr,0,n-1);
for(int i=0;i<n;i++) cout<<arr[i]<<' ';
cout<<endl;}
return 0;
}
2201: 第k大元素
题目描述
输入一个整数数组,请求出该数组的第k大元素。要求时间复杂度为O(n)。
输入
每组输入包括两行,第一行为k值;第二行为一个整数数组,两个数字之间用空格隔开。数组中元素个数小于1000。
输出
输出第k大元素的值,每个结果占一行
样例输入 Copy
2 3 2 1 5 6 4
样例输出 Copy
5
def findKth(s, k):
return findKth_c(s, 0, len(s) - 1, k)
def findKth_c(s, low, high, k):
m = partition(s, low, high)
if m == len(s) - k:
return s[m]
elif m < len(s) - k:
return findKth_c(s, m + 1, high, k)
else:
return findKth_c(s, low, m - 1, k)
def partition(s, low, high):
pivot, j = s[low], low
for i in range(low + 1, high + 1):
if s[i] <= pivot:
j += 1
s[i], s[j] = s[j], s[i]
s[j], s[low] = s[low], s[j]
return j
for _ in range(1000):
k = int(input())
s = list(map(int, input().split()))
print(findKth(s, k))
1668: 找中位数
题目描述
请设计一个算法,不排序,快速计算出一个无序数列的中位数。 时间复杂度要求为O(n)。
如果有奇数个元素,中位数则是数组排序后最中间的那个数字。
如果是偶数个元素,中位数则是数组排序后最中间两个元素的平均值。
输入
有多组输入,每组输入的第一行为n(1<=n<=1e5),表示该数列的元素个数。
第二行为n个整数组成的无序数列
输出
每组样例输出一行,表示该无序数列的中位数。
若为偶数,请保留三位小数
若为奇数,直接输出
样例输入 Copy
5 5 3 2 1 4
样例输出 Copy
3
import java.text.DecimalFormat;
import java.util.Scanner;
public class Main {
static void swap(int a[],int i,int j){
int t;
t=a[i];
a[i]=a[j];
a[j]=t;
}
public static int partition(int a[],int p,int q){
int x=a[p],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 int quickselect(int a[],int s,int t,int k) {
if(s==t)
return a[s];
int i=partition(a,s,t);
int j=i-s+1;
if(k<=j)
return quickselect(a,s,i,k);
else
return quickselect(a,i+1,t,k-j);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan=new Scanner(System.in);
while(scan.hasNextInt()) {
int k=scan.nextInt();
int[] a=new int[k];
for(int i=0;i<a.length;i++) {
a[i]=scan.nextInt();
}
if(k%2!=0) {
int res1=quickselect(a,0,k-1,k/2+1);
System.out.println(res1);
}
else {
int m=quickselect(a,0,k,k/2);
int n=quickselect(a,0,k,k/2+1);
double res2=(m+n)/2.0;
DecimalFormat df2 = new DecimalFormat("###.000");
System.out.println(df2.format(res2));
}
}
}
}
1422: 棋盘覆盖问题
题目描述
在一个n×n (n = 2k)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。
在棋盘覆盖问题中,要用4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
输入
多组测试用例,每组测试用例包括两部分,
第一部分为方格的宽度n,
第二部分则为方格,特殊方格为-1,其他方格为0。
输出
输出覆盖后的方案
样例输入 Copy
4 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
样例输出 Copy
-1 2 4 4 2 2 1 4 3 1 1 5 3 3 5 5
#include <stdio.h>
#include <stdlib.h>
int flag=1;
int a[1000][1000]={0};
void f(int tr,int tc,int dr,int dc,int n){
if(n==1)
return ;
int t=flag++;
int s=n/2;
//左上角
if(dr<tr+s&&dc<tc+s)
f(tr,tc,dr,dc,s);
else{
a[tr+s-1][tc+s-1]=t;
f(tr,tc,tr+s-1,tc+s-1,s);
}
//左下角
if(dr>=tr+s&&dc<tc+s)
f(tr+s,tc,dr,dc,s);
else{
a[tr+s][tc+s-1]=t;
f(tr+s,tc,tr+s,tc+s-1,s);
}
//右上角
if(dr<tr+s&&dc>=tc+s)
f(tr,tc+s,dr,dc,s);
else{
a[tr+s-1][tc+s]=t;
f(tr,tc+s,tr+s-1,tc+s,s);
}
//右下角
if(dr>=tr+s&&dc>=tc+s)
f(tr+s,tc+s,dr,dc,s);
else{
a[tr+s][tc+s]=t;
f(tr+s,tc+s,tr+s,tc+s,s);
}
}
int main(){
int n,i,j,p,q;
while(scanf("%d",&n)!=EOF)
{
flag=1;
for(i=0;i<n;i++){
for(j=0;j<n;j++)
{
scanf("%d",&a[i][j]);
if(a[i][j]==-1){
p=i;
q=j;
}
}
}
f(0,0,p,q,n);
for(i=0;i<n;i++){
for(j=0;j<n;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
}
}
1677: 第k小元素问题
题目描述
输入一个整数数组,请求出该数组的第k小元素。要求时间复杂度为O(n)。
输入
每组输入包括两行,第一行为一个整数数组,两个数字之间用空格隔开;第二行为k值。数组中元素个数小于1000。
输出
输出第k小元素的值。
样例输入 Copy
2 5 6 1 8 7 9 2
样例输出 Copy
2
import java.util.Scanner;
public class Main {
static void swap(int a[],int i,int j){
int t;
t=a[i];
a[i]=a[j];
a[j]=t;
}
public static int partition(int a[],int p,int q){
int x=a[p],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 int quickselect(int a[],int s,int t,int k) {
if(s==t)
return a[s];
int i=partition(a,s,t);
int j=i-s+1;
if(k<=j)
return quickselect(a,s,i,k);
else
return quickselect(a,i+1,t,k-j);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan=new Scanner(System.in);
while(scan.hasNextInt()) {
String str1=scan.nextLine();
String str2=scan.nextLine();
int k=Integer.parseInt(str2);
String[] str=str1.split(" ");
int[] a=new int[str.length];
for(int i=0;i<a.length;i++) {
a[i]=Integer.parseInt(str[i]);
}
int res=quickselect(a,0,a.length-1,k);
System.out.println(res);
}
}
}