数组双指针,通常指利用两个指针,对数组进行操作。常见的双指针,为头尾双指针,如下图所示:
通过前后两个指针,对数组进行操作。
例如:
包含n个整数的数组,要求我们将数组翻转过来后,再进行输出。
我们可以使用两个指针,一个在数组开头,一个在数组末尾,每次将指针指向的两个数进行交换,
即可得到翻转后的数组
归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
以下是归并排序的示意图:
以下是二路归并的示意图:
从上面二路归并的示意图可以看出,合并操作的平均时间复杂度为O(n),比选用sort排序节省时间
一个数组如果正反读一样,就叫回文数组,比如: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;
}
一年一度的士兵素质考核即将开始了,每个郡都会选出部分士兵,到中心城参加考核,为了公平,距离中心城越远的地方,可以越早进入中心城,以缓解旅途的疲劳。中央城的士兵不需要参加考核,即中心城参加考核人数为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;
}
元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品,并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。
你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。
数据范围及提示:
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;
}
有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;
}