php面试题目 解题

有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗?

<?php
error_reporting(E_ALL ^ E_NOTICE);
class mostarea{


    function print_area($n,$a,$k,$d){
        //引用 数据
        //$n=$this->n;
        //$a=$this->a;
        //$k=$this->k;
        //$d=$this->d;
        $s_value="1";//
        /*+++
        /*  要想选出最大值能力值,一定是最大能力值相乘,所以问题就变成了找到满足d的值
        /*  先排序,选出最大的能力值  如果第二大的值的编号满足d,则用第二大值,不满足则选一个最大值
        +++*/
        $a_order=$a;
        arsort($a_order);//arsort按降序排序,不改变键值
        //按最大值取出最大值及对应的编号
        $i=0;
        foreach($a_order as $key=>$val){
           $a_order_arr[$i]["key"]=$key;//
           $a_order_arr[$i]["val"]=$val;//
           $i++;
        }
        if($d<0){
          $d=abs($d);//对差值取正,
        }
        //从最大值排序开始计算
        for($i=0;$i<$n;$i++){//
            $m=0;
            $k_v=1;
            for($sc=0;$sc<$k_v;$sc++){//
                if($sc==0){            
                    $max_val[$i][$m]["val"]=$a_order_arr[$i]["val"];//最大值
                    $max_val[$i][$m]["key"]=$a_order_arr[$i]["key"];//最大值
                }

                //$max_key[$i][$m]=$a_order_arr[$i]["key"];//最大值对应的编号
                //在这个最大值范围内取出$a_key[$i]-$d到	$a_key[$i]+$d
                $left_one=$max_val[$i][$m]["key"]-$d;
                if($sc==0){
                    $left_one=$max_val[$i][$m]["key"]-$d;
                }else{
                    $left_one=$max_val[$i][count($max_val[$i])-1]["key"]-$d;
                }
                  //$new_arr_1[$i]=array_slice($a,$left_one,(2*$d+1));//下面相当于函数array_slice
                  $nf=0;
                  if($left_one<0){
                      $left_one=0;
                  }
                  $get_count[$i]=$left_one+2*$d+1;
                  if(($n-1)<$get_count[$i]){
                     switch($n){
                        case "1":
                        $get_count[$i]=1;
                        break;
                        default:
                        $get_count[$i]=$n;
                     }               
                  }
                  if($sc==0){
                    $new_a[$i]=$a;//将当前数组赋值给一个新的数组
                  }else{
                    $new_a[$i]=$new_a[$i];//
                  }

                  $new_a[$i][$max_val[$i][$m]["key"]]="";//置空当前值
                  //show($new_a);
                  for($f=$left_one;$f<$get_count[$i];$f++){
                      //if($new_a[$i][$f]){
                          $new_arr[$i][$sc][$nf]["val"]=$new_a[$i][$f];
                          $new_arr[$i][$sc][$nf]["key"]=$f;
                          $nf++;
                     // }
                  }
                  if(0<$sc){
                      //show($new_arr);
                  }
                  if($sc==0){
                     //show($new_arr); 
                  }
                  //计算新数组满足d条件的第2大值
                  if(1<count($new_arr[$i][$sc])){
                     arsort($new_arr[$i][$sc]); 
                  }
                  if(empty($new_arr[$i][$sc]) ||count($new_arr[$i][$sc])==1){//数组key最左只能是0
                    $s_count=0;//
                  }else{
                    $s_count=1;
                  }
                  //show($new_arr[$i][$sc]);
                  for($s=0;$s<$s_count;$s++){
                    //当前指针的的值和key
                    if(0==$s){
                        $second_val_arr[$i][$s]=current($new_arr[$i][$sc]);  
                    }else{
                        $second_val_arr[$i][$s]=next($new_arr[$i][$sc]);
                    }
                    $second_val[$i][$s]=$second_val_arr[$i][$s]["val"];            
                    $second_key[$i][$s]=$second_val_arr[$i][$s]["key"];        
                    //单再次排列的值满足d
                    $d_value[$i][$s]=abs(($max_val[$i][$m]["key"])-$second_key[$i][$s]);
                    if($d_value[$i][$s]<=$d){
                        //if(count($max_val[$i])<=$k){
                            $m=$m+1;
                            $max_val[$i][$m]["val"]=$second_val[$i][$s];
                            $max_val[$i][$m]["key"]=$second_key[$i][$s];
                            if(count($max_val[$i])==$k){
                              break;  
                            }
                    }else{
                        if($s_count<=$n){
                          $s_count++; //这个范围不满足继续找 
                        }
                      }
                    }
                //show(count($max_val[$i]));
                if(count($max_val[$i])<$k && $k_v<=$n){
                    $k_v++;
                }
            }
            //按原来key值排序
            foreach($max_val[$i] as $o_val){//
                  $key_array[$i][]=$o_val['key'];
            }
            array_multisort($key_array[$i],SORT_ASC,SORT_NUMERIC,$max_val[$i]);
            //计算乘积
            $last_val[$i]=1;
            for($cj=0;$cj<$k;$cj++){
                if($max_val[$i][$cj]["val"]){
                  $last_val[$i]=$last_val[$i]*$max_val[$i][$cj]["val"];
                  $max_val[$i][$cj]["key"]=$max_val[$i][$cj]["key"]+1;//key代表数组,真实从1开始
                  $last_key[$i]=($last_key[$i] || $last_key[$i]==0)?$last_key[$i].",".$max_val[$i][$cj]["key"]:$max_val[$i][$cj]["key"];
                }
            }

            $obj[$i]["val"]=$last_val[$i];
            $obj[$i]["key"]=$last_key[$i];
        }
           return $obj;
        }
        function get_val(){
            $a=new mostarea();
            $n=5;
            $a=array("1","10","5","22","99");
            $k=2;
            $d=1;
            $value=$this->print_area($n,$a,$k,$d);
            rsort($value);
            echo "输入:";
            echo "<br>";
            echo "---".$n."排";
            echo "<br>";
            echo "---".implode($a," , ");
            echo "<br>";
            echo "--- 选取".$k."人";
            echo "<br>";
            echo "---差值不超过:".$d;
            echo "<br>";
            echo "选取结果:";
            echo "<br>";
            echo "<<<"."最大值:".$value[0]["val"];
            echo "<br>";
            echo "<<<"."编号选择:".$value[0]["key"];
        }
}
$a=new mostarea();
$a->get_val();
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值