数组双指针移动和有序数组的合并(c++语言)

数组双指针,通常指利用两个指针,对数组进行操作。常见的双指针,为头尾双指针,如下图所示:

2.png

通过前后两个指针,对数组进行操作。

例如:

包含n个整数的数组,要求我们将数组翻转过来后,再进行输出。

我们可以使用两个指针,一个在数组开头,一个在数组末尾,每次将指针指向的两个数进行交换,

即可得到翻转后的数组

归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并

以下是归并排序的示意图:

1.png

以下是二路归并的示意图:

2.jpg

3.jpg

从上面二路归并的示意图可以看出,合并操作的平均时间复杂度为O(n),比选用sort排序节省时间

第1题     回文数组的判断 查看测评数据信息

一个数组如果正反读一样,就叫回文数组,比如:12, 35, 12。
输入n个整数的数组,判断它是不是回文数组。如果是输出”Yes”,否则输出”No”。

输入格式

第一行1个整数n,范围在[1,100]。
 第二行有n个[1,10000]范围的整数,整数间用一个空格分隔。

输出格式

Yes或No。

输入/输出例子1

输入:

5

1 2 3 2 1

输出:

Yes

#include<bits/stdc++.h>
using namespace std;
int a[105],n,ans;
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];      
    if(n%2==1)
    {
         for(int i=0;i<=n/2-1;i++)
         {
             if(a[1+i]==a[n-i])
             ans++;
         }
     } 
    else
    {
        for(int i=0;i<=(n+1)/2-1;i++)
        {
            if(a[1+i]==a[n-i])
            ans++;    
        }
    }      
    if(ans==n/2)
    {
         cout<<"Yes";
            
     }
     else
     {
         cout<<"No";
           
     }       
        return 0;
}
第2题     素质考核 查看测评数据信息

一年一度的士兵素质考核即将开始了,每个郡都会选出部分士兵,到中心城参加考核,为了公平,距离中心城越远的地方,可以越早进入中心城,以缓解旅途的疲劳。中央城的士兵不需要参加考核,即中心城参加考核人数为0。

输入n个整数,表示每个郡参加考核的士兵人数,n为奇数,第一个数和最后一个数表示距离中央城最远的两个郡,以此类推,中间的数为0,表示中央城参与考核人数为0。

要求输出每天到达中央城的士兵人数。

输入格式

 第一行1个整数n(奇数),范围在[1,100000]。
 第二行有n个[1,10000]范围的整数,整数间用一个空格分隔。

输出格式

 (N-1)/2个整数。

输入/输出例子1

输入:

9

4 2 5 1 0 3 1 5 7

输出:

11 18 24 28

#include<bits/stdc++.h>
using namespace std;
int n,a[100005],sum=0;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	for(int i=1,j=n;i<=n/2;i++,j--){
		cout<<a[i]+a[j]+sum<<" ";
		sum+=a[i]+a[j];	
	}
	return 0;
}
第3题     纪念品分组 查看测评数据信息

元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品,并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。
你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。
数据范围及提示:
50%的数据满足:1 <= n <= 15
100%的数据满足:1 <= n <= 30000, 80 <= w <= 200

输入格式

包含n+2行:
第1行包括一个整数w,为每组纪念品价格之和的上限。
第2行为一个整数n,表示购来的纪念品的总件数。
第3~n+2行每行包含一个正整数pi (5 <= pi <= w),表示所对应纪念品的价格。

输出格式

仅一行,包含一个整数,即最少的分组数目。

输入/输出例子1

输入:

100

9

90

20

20

30

50

60

70

80

90

输出:

6

#include<bits/stdc++.h>
using namespace std;
int a[30000];
int main(){
	int w,n;
	while(cin>>w>>n){
		for(int i=0;i<n;i++)
			cin>>a[i];
		sort(a,a+n);
		int top,rot,ans;
		top=0,rot=n-1,ans=0;
		while(top<=rot){
			if(a[top]+a[rot]<=w)top++,rot--,ans++;
			else rot--,ans++;
		}
		cout<<ans;
        break;
	}	
    return 0;
} 
有序数组的合并2 查看测评数据信息

有N个正整数,前一半属于a数组,后一半属于b数组,a,b数组都为从小到大排序的数组,要求把两个数组合并,并使新的数组仍然是有序的,输出新数组。

输入格式

第一行1个正整数:N,范围在[1,8000000]。
 第二行N个可以相同的正整数:范围在[1,8000000]。

输出格式

一行:合并后的数组

输入/输出例子1

输入:

6

1 3 5 2 4 6

输出:

1 2 3 4 5 6

#include<bits/stdc++.h>
using namespace std;
int n,a[8000005];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    int i=1,j=n/2+1;
    for(;;){
        if(i>n/2||j>n)
            break;
        else if(a[i]<a[j]){
            cout<<a[i]<<' ';
            i++;
        }
        else if(a[i]==a[j]){
            cout<<a[i]<<' '<<a[j]<<" ";
            i++;
            j++;
        }
        else{
            cout<<a[j]<<" ";
            j++;
        }
    }
    for(;i<=n/2;i++){
        cout<<a[i]<<' ';
    }
    for(;j<=n;j++){
        cout<<a[j]<<' ';
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值