您的位置:首页 > 其它

水桶阀门问题

2008-10-18 18:40 120 查看
有n个水桶,组成一个环,相邻两个有水管连接,
水管中间有阀门,都关上。

初始条件是:水桶有水,深度不一,保存在数组a
里面。
问:设计算法,针对具体的a
,使得打开阀门最少情况下,水桶深度相同。
时间复杂度<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);
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐