zoukankan      html  css  js  c++  java
  • 水桶阀门问题

    有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);
    }
    
    
  • 相关阅读:
    Irrlicht_0.1源码学习(3)—Irrlicht.cpp & include/Irrlicht.h
    Irrlicht_0.1源码学习(2)—引擎目录结构
    Irrlicht_0.1源码学习(1)—Welcome to the Irrlicht Engine
    Visual Studio 2013 编译时 "error LNK2026:模块对于 SAFESEH 映像是不安全的" 解决方案
    Windows平台下Lua环境的搭建
    系统调用与API
    前端学习技巧分享
    简单的bootstarp项目实例
    js显示表单的提交验证
    拷贝一张图片,从一个目录到另外一个目录下(PS:是拷贝是不是移动)
  • 原文地址:https://www.cnblogs.com/CUCmehp/p/1314147.html
Copyright © 2011-2022 走看看