算法与数据结构:1——将一个数组四等分
将一个数组四等分
1. 问题描述:
给定一个数组,在数组(array)中取三个元素,\(a_i\),\(a_j\),\(a_k\) ,并且保证\(i<j<k\) ,此时如果存在区间[\(a_0\),\(a_i\)),(\(a_i\),\(a_j\)),(\(a_j\),\(a_k\)),(\(a_k\),\(a_{n-1}\)],四个区间内之相等,则说该数组可以被四等分。(\(a_n\)表示的是最后一个元素)
2.基本思路
假设m1,m2,m3一次为四个分段数组的分界线。用两个指针\(i\),\(j\)分别指向数组数组第一个元素和最后一个元素。令s1=\(a_i\),s2=\(a_j\),而后开始进行如下操作:
while (\(i<j\))
- 如果s1==s2,则返回\(i\),\(j\) 的数值,跳出循环
- 如果s1>s2,则\(j=j-1\),且s2=s2+\(a_j\)
- 如果s1<s2,则\(i=i+1\),且s1=s1+\(a_i\)
这样的话,上面的到的\(i和j\)就可以作为m1,和m3的候选之一,即求出的分段数组和为sum1
而后对array[m1+1,m3-1]进行而等分,如果可以,并且等分后,分段数组的值和sum2,如果sum1==sum2,则找到四等分点;否则令i=m1,j=m3,array[i+1,j-1]的区间再次寻找候选解m1和m2,使得sum(array[0~m1-1])==sum(array[m3+1~n-1])(这一点非常容易出错).
3.C++代码
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstddef>
#include <vector>
using namespace std;
bool split(vector<int>&Array,int& m1,int& m2,int& sum){
int i=m1;
int j=m2;
int slow,shigh;
slow=Array[i];
shigh=Array[j];
while(i<j){
if(slow==shigh){
break;
}
if(slow<shigh){
++i;
slow += Array[i];
}else{
--j;
shigh +=Array[j];
}
}
if(slow==shigh && i<j ){
m1=i+1;
m2=j-1;
sum += slow;
return true;
}else
{
m1=i+1;
m2=j-1;
sum += slow;
return false;
}
}
bool splitArrayFourSlice(vector<int>&Array,int& m1,int& m2,int& m3){ // 将数组四等分
if(Array.size()<7){
cout<<"The input array not meet coditions"<<endl;
exit(1);
}
bool res=false;
int low,high;
int sum1,sum2;
sum1=0;
sum2=0;
m3=Array.size()-1;
low=m1;
high=m3;
while( low<=high){
if(!split(Array,low,high,sum1) ){
break;
}
m1=low;
m3=high;
++low;
--high;
sum2=0;
while( split(Array,low,high,sum2) && low<high)
;
if(low==high && sum1==sum2){
m2=low;
res=true;
break;
}else{
low=m1;
high=m3;
}
}
return res;
}
int main(){
int A[]={2,5,1,1,1,1,4,1,7,3,7};
int B[]={2,5,7,1,1,1,1,4,7,1,7,7,3,7,3,4};
int C[]={2,3,2,1,2,3,2};
int D[]={2,2,3,2,2,1,2,2,3,2,2};
int E[]={2,2,3,2,2,1,2,2,3,2,2,1};
vector<int> A1(A,A+11);
vector<int> B1(B,B+16);
vector<int> C1(C,C+7);
vector<int> D1(D,D+11);
vector<int> E1(E,E+12);
int m1=0,m2=0,m3=0;
if(splitArrayFourSlice(E1,m1,m2,m3)){
cout<<"m1= "<<m1<<" m2= "<<m2<<" m3= "<<m3<<endl;
}else{
cout<<"error"<<endl;
}
return 0;
}

浙公网安备 33010602011771号