有n个水桶,组成一个环,相邻两个有水管连接,
水管中间有阀门,都关上。

初始条件是:水桶有水,深度不一,保存在数组a[n]里面。
问:设计算法,针对具体的a[n],使得打开阀门最少情况下,水桶深度相同。
时间复杂度<O(n^2),最佳是o(N).

 

我写的这个算法,复杂度为o(n^2),不知道能不能优化到O(n).

算法如下:

 

#include<iostream> 
#include
<list>
using namespace std;
class bucket{
public:
double water;
bool valid;
bool left;
bool right;
double orgWater;
bucket(
double w):water(w){
valid
=true;
left
=false;
right
=false;
orgWater
=w;
}
};
double abs(double d){
return d>=0?d:-d;
}
list
<bucket>::iterator getMaxIndex(list<bucket>& v){
double max=0;
list
<bucket>::iterator index=v.end();
for(list<bucket>::iterator it=v.begin();it!=v.end();it++){
if((*it).valid&&abs((*it).water)>max){
max
=abs((*it).water);
index
=it;
}
}
return index;
}
void getlastIter(list<bucket>& v,list<bucket>::iterator& it){
it
=v.begin();
for(int i=1;i<v.size();i++){
it
++;
}
}
void moveToRight(const list<bucket>& v,list<bucket>::const_iterator& it){
it
++;
if(it==v.end()){
it
=v.begin();
}
if((*it).valid==true){
return;
}
else{
moveToRight(v,it);
}
}
void moveToLeft(list<bucket>& v,list<bucket>::iterator& it){
if(it==v.begin()){
getlastIter(v,it);
}
else{
it
--;
}
if((*it).valid==true){
return;
}
else{
moveToLeft(v,it);
}
}
bool getRight(const list<bucket> &v,const list<bucket>::iterator start,double& sum,list<bucket>::iterator it){
if(it==start)//已经转了一圈
return false;
if((*it).valid==false){
moveToRight(v,it);
return getRight(v,start,sum,it);
}
else{
sum
+=(*it).water;
return true;
}
}
bool getLeft(list<bucket> &v,list<bucket>::iterator start,double& sum,list<bucket>::iterator it){
if(it==start)//已经转了一圈
return false;
if((*it).valid==false){
moveToLeft(v,it);
return getLeft(v,start,sum,it);
}
else{
sum
+=(*it).water;
return true;
}
}
void print(const list<bucket>& l){
for(list<bucket>::const_iterator it=l.begin();it!=l.end();it++){
if((*it).right){
cout
<<(*it).orgWater<<"右边打开"<<endl;
}
if((*it).left){
cout
<<(*it).orgWater<<"左边打开"<<endl;
}
}
}
void init(list<bucket>& v){
double max=0;
for(list<bucket>::iterator it=v.begin();it!=v.end();it++){
max
+=(*it).orgWater;
}
for(list<bucket>::iterator it=v.begin();it!=v.end();it++){
(
*it).water-=max/v.size();
}
}
void algorithm(list<bucket>& v){
init(v);
list
<bucket>::iterator index=getMaxIndex(v);
double max=(*index).water;
while(max!=0){
double leftSum=max;
double rightSum=max;
list
<bucket>::iterator left=index;
list
<bucket>::iterator right=index;
moveToLeft(v,left);
moveToRight(v,right);
while(getLeft(v,index,leftSum,left)){
getRight(v,index,rightSum,right);
moveToLeft(v,left);
moveToRight(v,right);
if(leftSum!=rightSum){
break;
}
}
if(abs(leftSum)<=abs(rightSum)){
list
<bucket>::iterator temp=index;
moveToLeft(v,temp);
(
*index).left=true;
(
*temp).right=true;
(
*temp).valid=false;
(
*index).water+=(*temp).water;
}
else{
list
<bucket>::iterator temp=index;
moveToRight(v,temp);
(
*index).right=true;
(
*temp).left=true;
(
*temp).valid=false;
(
*index).water+=(*temp).water;
}
index
=getMaxIndex(v);
if(index==v.end())
break;
max
=(*index).water;
}
}
int main(){
list
<bucket> v;
v.push_back(
1);
v.push_back(
4);
v.push_back(
7);
v.push_back(
1);
v.push_back(
6);
v.push_back(
0);
v.push_back(
2);
algorithm(v);
print(v);
}

posted on 2008-10-18 18:40  CUCmehp(likesmiles)  阅读(335)  评论(0编辑  收藏  举报