php编程解决问题

1:100盏灯开关:

大厅里有100盏灯,每盏灯都编了号码,分别为1-100。每盏灯由一个开关来控制。(开关按一下,灯亮,再按一下灯灭。开关的编号与被控制的灯相同。)开始时,灯是全灭的。现在按照以下规则按动开关。
第一次,将所有的灯点亮。
第二次,将所有2的倍数的开关按一下。
第三次,将所有3的倍数的开关按一下。
以此类推。第N次,将所有N的倍数的开关按一下。
问第100次按完以后,大厅里还有几盏灯是亮的。

//  方法1:双重for循环,外层控制,第1次...第100次;内层控制100盏灯;每次中,从1到100盏灯哪些灯发生变化;

$arr = array_fill(1,100,0);          // 构造100盏灯;  初始:等全部灭的,用0代替;  0表示灯灭;
                                     
$cishu = 1;

for($cishu = 1;$cishu<=100;){       // 从第一次到第100次;

	for($i = 1;$i<=100;$i++){       //  从第1盏灯到第100盏灯;
		
		if($i%$cishu==0){           // 从100盏灯中依次找出,判断找出符合改变状态的灯;      
			
			$arr[$i] = ~($arr[$i]);    // 改变 符合条件的灯 的状态。 (注意:0取反的结果是-1,-1再取反又是0);
			
		}
    }
	
	$cishu++;                 // 第$cishu次运行结束,再循环$cishu+1次,根据条件,改变每盏灯的变化;

}

for($i = 1;$i<=100;$i++){
	
    if($arr[$i]==-1){       // 0的取反是-1;所以状态是-1的时候,表示灯在亮着;
		
		echo $i;
		echo '<br/>';
	}
}
//  方法2:外层循环依旧用for循环来逐一运行每一次; 内层循环利用foreach,遍历出每盏灯的健名和状态(值);

$arr = array_fill(1,100,0);          // 构造100盏灯;  初始:等全部灭的,用0代替;  0表示灯灭;
                                     
$cishu = 1;

for($cishu = 1;$cishu<=100;$cishu++){
	
	foreach($arr as $keys => $values){
		
		if($keys%$cishu==0){
			
			//① :$arr[$keys] = ($values==0)?1:0;  三目运算的方法:(成不成立?1:0)
			
			$arr[$keys] = $values ^ 1;    //异或(位)运算; (0^1==1;1^1==0);  ②;
			
			//③ : arr[$keys] = $values+1   // 每次的值(状态)都加1,(0关,1开,2关,3开,4关,5开,6关...最后被2整数余1的表示状态 开);
			
			/***   ④    **
			
			条件判断,赋值改变法;类似于 上面的三目运算;
			
			if($values==0){
				
				$arr[$keys] = 1;
			}else{
				
				$arr[$keys] = 0;
			}
			
		   ********/
		}
	}
	
}


foreach($arr as $keys=>$values){
	
	if($values==1){
		
		echo $keys.'====>'.$values;//(值表示状态,都为1表示开着,健名表示灯的标号,哪些标号的灯开着最后);
		echo '<br/>';
	}
}

2:逢三退一:

有10个人(编号1-10) 围成一个圈 从第一个开始数 数到三 踢出这个人 然后接着往下循环数! 直到剩下一个人为止! 问最后剩下的那个人的编号是几?

// 方法1 :假设原先有10个人,都为true,数到3的时候,那个人变为false,最后剩余的那个true就为所求的;


$tenarr = array_fill(1,10,true);    // 构造10个人,初始都标识为true;

$jishu = 0;                        // 计数初始为0,数到3后,再重新开始;

$keys = 1;                        // 数组下标初始为1,到10结束;

$truegeshu = count($tenarr);     //  标识为true的个数,初始为10,数到3的时候,减一;

while($truegeshu>1){
	
	if($tenarr[$keys]==true){      // 如果标识是ture,说明还在圈中;
		
		$jishu++;
		if($jishu==3){               //数到3的时候;
			$jishu = 0;              //  重新下一次计数,初始;
			$tenarr[$keys]=false;    //   将标记true变成false; 退出;
            $truegeshu--;          //   标识为true的个数少一个;			
		}
	}
	
	$keys++;                       // 进入下一个数;
	if($keys>count($tenarr)){   // 如果下标的值,大于总个数的时候,(从1开始的,即:$keys>10);
	// $keys=count($tenarr)+1
	   $keys = 1;                  // 假如下标数到11的时候,超过了10个总数,从1继续开始;	
	}
}


foreach($tenarr as $ks=>$vs){
	
	if($vs==true){
		echo $ks;         // 4;  数组的下标从1开始设置并计算的;   
	}
}

// 方法2 :利用php数组特性处理;

$arr2 = range(1,10);    //构造一个数组,值代表10个人以及对应的编号;

$jishu = 0;             // 计数器;初始为0,到3还原;

while(count($arr2)>1){
	
	foreach($arr2 as $keys=>$values){
		
		$jishu++;
		if($jishu==3){
			
			unset($arr2[$keys]);       // 直接从数组中,剔除出去;
			$jishu = 0;
		}
	}
}

print_r($arr2);       // Array ( [3] => 4 );  原数组中,只剩1个数值;

// 方法3: 利用aarray_splice()函数去除,改变原数组的值以及下标;(只去除,没有替换);

$arr3=array('1','2','3','4','5','6','7','8','9','10');

function leftOne($arr) {
		
	$num = count($arr);
	$count = 0;
	for ($j = 0; $j < $num; $j++) {
		$count++;               
		$diff = count($arr);
		if (2*$count >= $diff) {   
			array_splice($arr, 2*$count - $diff, 1);
			$count = 0;
		}else {
			array_splice($arr, 2*$count, 1);
		}
	}
	  return $arr[0];
}

echo leftOne($arr3);

3:小球落地:

一球从100米高度自由落下,每次落地后反跳回原高度的一半,再落下,求它在第10次落地时,共经历多少米,第10次反弹多高?

       $s = 100;     // 第一次从100米开始落地;
	   $h = 50;      // 从反弹的高度h=50开始,一个周期为 2*h;
	   
	   for($i=2;$i<=10;$i++){                   //  从第一次落地后反弹,到第二次落地是一个循环周期;   反弹的高度$h = 50;
		   
		   $s = $s+2*$h;
		   $h = $h/2;
	   }
       
	   echo $s;
	   echo $h;

4:取各不相同的牌:

有9张牌每张是不一样的,在里面任意取3张,且3张牌中各不相同,一共有多少种取法?

$kk= 0;

for($i = 0;$i<=8;$i++){
	
	for($j = $i;$j<=8;$j++){
		
		for($k = $j;$k<=8;$k++){
			
			  if(($i!=$j)&&($j!=$k)&&($i!=$k)){
				  
				  $kk++;
			  }	
	    }
	}
	
}

echo $kk;

5:乒乓比赛匹配:

两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。

for($i = 1;$i<=3;$i++){                      // $i a的对手,从xyz(1,2,3)中选其中一个;
	
	for($j = 1;$j<=3;$j++ ){                // $j b的对手,从xyz(1,2,3)中选其中一个;
		
		for($k = 1;$k<=3;$k++){            //  $k b的对手,从xyz(1,2,3)中选其中一个;
			
			if(($i!=1)&&($k!=1)&&($k!=3)&&($i!= $j)&&($i!= $k)&&($j!= $k)){    // 还需要保证 abc的对手不能有相同的,(一个人不能参加两场比赛);
				
				echo 'a'.'-----'.$i;             //  a-----3;
				echo 'b'.'-----'.$j;             //  b-----1;
				echo 'c'.'-----'.$k;             //  c-----2;
				
			}
			
		}
		
	}    
	
}

6:猴子搬香蕉:

一只猴子旁边有100根香蕉,猴子离家50米;一次最多搬50根香蕉;但猴子每走1米就要吃掉1根香蕉,问猴子最多能拿回家多少香蕉?

$xiangjiao = 100;

for($juli =1;$juli<=50;$juli++){
     
    if($xiangjiao>=50){
		$xiangjiao -= 3; 
	}else{
		$xiangjiao -= 1; 
	}
    echo '走到第'.$juli.'米时','香蕉剩余'.$xiangjiao;
    echo '<br/>';	
}

7:规律数字求和:

一组数字 1,1,2,3,5,8,13.........求其前20项的和;

// 方法1:利用迭代、替换求和;

$a = 1;

$b = 1;

$s = 2;

$m = 0;

for($i=3;$i<=20;$i++){
	
	$m = $a+$b;
	$s = $s+$m;
	
	$a = $b;
	$b = $m;
	
}

echo $s;     //  17710;

// 方法2:利用函数递归,得出每一项的值,然后求和;

function qiuhe($n){
	
	if($n>2){
		
		return qiuhe($n-1)+qiuhe($n-2);
		
	}
	
	if($n=2){
		
		return 1;
	}
	
	if($n=1){
		
		return 1;
	}
	
}

$sum = 0;

for($i=1;$i<=20;$i++){
	
	$sum += qiuhe($i);	
}

echo $sum;          // 17710;


// 方法3:利用数组,算出每个元素的值,然后求和;

$arr[0] = $arr[1] = 1;

for($i=2;$i<20;$i++){
	
	$arr[$i] = $arr[$i-1] + $arr[$i-2];
}

echo array_sum($arr);   //  17710;



8:百钱白鸡:

公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱,用100文钱买一百只鸡,其中公鸡,母鸡,小鸡都必须要有,问公鸡,母鸡,小鸡要买多少只刚好凑足100文钱。

for($x=1;$x<20;$x++){   // 公鸡x只;
  
  for($y=1;$y<34;$y++){   // 母鸡y只;
   
    $z = 100- $x - $y;     // 母鸡z只;	
	
    if((5*$x + 3*$y + $z/3) == 100){
		
		echo '公鸡'.$x.'只'.'    '.'母鸡'.$y.'只'.'    '.'小鸡'.$z.'只'.'    ';
		echo '<br/>';
	}
	
  }
   	
}

8:过路口问题:

假设某人有100,000现金。每经过一次路口需要进行一次交费。交费规则为当他现金大于50,000时每次需要交5%如果现金小于等于50,000时每次交5,000。请写一程序计算此人可以经过多少次这个路口。

//  while循环方法;

$money = 100000;

$lukou = 0;

while($money > 5000){
	
	if($money > 50000){
		$money *= 0.95;
	}else{
		$money -= 5000;
	}
	
	$lukou++;
	
	echo '过了'.$lukou.'个路口','钱还剩于'.$money;
	echo '<br/>';
}


//  for循环方法; for(初始化;循环语句;执行循环后语句)

for($money = 100000,$num=0;$money >= 5000;$num++) {
	if($money > 50000) {
	    $money *= 0.95; // 扣了5%,即原来的0.95倍
	} else {
	    $money -= 5000;
	}
}

echo $num;

9:猴子吃桃问题:

猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。


// 方法1:
// 第一天摘了$i个桃子;  然后从1开始,寻找满足条件的;

for($i = 1;;$i++){
	
	$y = $i;
	
  for($d = 1; $d < 10;$d++){
	  
	  $y = $y/2 - 1;  
  }	
  
  if($y == 1){
	  
	  break;
  }
	
}

echo $i;       //  1534;
echo '<hr/>';

//  方法2: 第10天剩余1个,第9天的时候开始剩余4个(吃了3个);第8天的时候开始剩余10个(吃了6个);...

$sheng = 1;

for($i = 9;$i > 0;$i--){
	$sheng = 2*($sheng+1);
}
echo $sheng;    //  1534;

9:人分苹果问题:

有5个人偷了一堆苹果,准备在第二天分赃。晚上,有一人遛出来,把所有菜果分成5份,但是多了一个,顺手把这个扔给树上的猴了,自己先拿1/5藏了。没想到其他四人也都是这么想的,都如第一个人一样分成5份把多的那一个扔给了猴,偷走了1/5。第二天,大家分赃,也是分成5份多一个扔给猴了。最后一人分了一份。问:共有多少苹果?

for ($i = 1; ; $i++)
{
    if ($i%5 == 1) {
        //第一个人取五分之一,还剩$t
        $t = $i - round($i/5) - 1;      
        if($t % 5 == 1)
        {
            //第二个人取五分之一,还剩$r
            $r = $t - round($t/5) - 1;      
            if($r % 5 == 1)
            {
                //第三个人取五分之一,还剩$s
                $s = $r - round($r/5) - 1;              
                if($s % 5 == 1)
                {
                    //第四个人取五分之一,还剩$x
                    $x = $s - round($s/5) - 1;                  
                    if($x % 5 == 1)
                    {
                        //第五个人取五分之一,还剩$y
                        $y = $x - round($x/5) - 1;                      
                        if ($y % 5 == 1) {
                            echo $i;
                            break;
                        }
                    }
                }
            }
        }
    }
}

9:进制转换问题:

给两个参数,一个整数值A,代表需要转换的数字,一个整数B,代表返回值的宽度,要求获得,整数A的十六进制字符串,如果宽度不够B,那么前面用0补齐.

function dectohex($a,$b){
	
	$arryu = array();
	
	for(;;){
		
	   $yu = $a % 16;
	   
	   if($yu<10){
		   $arryu[] = $yu;
	   }else{
		   $temp = array('A','B','C','D','E','F');
		   $arryu[] = $temp[($yu - 10)];
	   }
	   
	   $a = floor($a/16);
	   
	   if($a == 0){
		   break;
	   }
	}
	
	$strs = strrev(implode($arryu));
	$strlen = strlen($strs);
	
	if($strlen < $b){
		
		for($i=0;$i<$b-$strlen;$i++){
			
			$strs = '0'.$strs;
			
		}
		
	}
	
	//  1、可以直接用str_pad函数来实现填充;
	//  2、也可以,数组先不转换成字符串,先在数组中追加到指定的长度,最后再转换成字符串,反转;
	
	return $strs;
}

echo dectohex(170,8)





猜你喜欢

转载自blog.csdn.net/prdslf001001/article/details/79000791