
先看下題目:有15個瓶子,瓶子中都裝有水,但是其中有一個瓶子的水是有毒的,現(xiàn)在有4只老鼠,老鼠喝了有毒的水后會在第二天死亡,如何設計老鼠喝水可以再第二天通過觀察老鼠的狀態(tài)來判斷哪個瓶子的水有毒?
分析一下題目:每瓶水對于每只老鼠來說都有喝或者不喝兩種狀態(tài),4只老鼠對于每瓶水都可以有 0000 -> 1111 16中狀態(tài),由于要確認有毒,所以舍棄掉第一種都不喝的狀態(tài)(0000),剩余15中狀態(tài)正好與15個瓶子一一對應,所以我們可以取瓶子編號的后4位(0001->1111)來對應4只,老鼠是否喝這瓶水的狀態(tài) 0代表喝 1代表不喝,最后根據(jù)4只老鼠的中毒狀態(tài)來代表4個bits就可以得到哪個瓶子有毒了。
理清了思路,就可以用代碼驗證一下了:
先根據(jù)題目創(chuàng)建老鼠和瓶子的類
@interface BottleWater : NSObject
// 是否有毒
@property (nonatomic,assign) BOOL poisonous;
@property (nonatomic,assign) NSUInteger num; // 編號
@end
@implementation BottleWater
-(NSString *)description
{
return [NSString stringWithFormat:@"%lu號瓶子,%@毒",_num,_poisonous?@"有":@"無"];
}
@end
@interface Mouse : NSObject
// 是否中毒
@property (nonatomic,readonly,assign) BOOL poisoning;
@property (nonatomic,assign) NSUInteger num;// 編號
@property (nonatomic,readonly,getter=nextDayStatus) BOOL isLiving;
@end
@implementation Mouse
@synthesize poisoning = _poisoning;
- (void)drinkWater:(BottleWater *)water
{
if (water.poisonous) {
_poisoning = YES;
}
}
- (BOOL)nextDayStatus
{
return !_poisoning;
}
-(NSString *)description
{
return [NSString stringWithFormat:@"%lu號老鼠%@中毒",_num,_poisoning?@"":@"未"];
}
@end
然后根據(jù)思路設計代碼:
首先創(chuàng)建瓶子和老鼠
// 創(chuàng)建瓶子
NSMutableArray <BottleWater *>*waters = [NSMutableArray arrayWithCapacity:1];
int poisoningNum = arc4random()%15+1;
NSLog(@"第%d瓶有毒",poisoningNum);
for (int i=1; i<=15; i++) {
BottleWater *water = [[BottleWater alloc] init];
water.num = i;
if (i == poisoningNum) {
water.poisonous = YES;
}
[waters addObject:water];
}
// 創(chuàng)建老鼠
NSMutableArray <Mouse *>*mouses = [NSMutableArray arrayWithCapacity:1];
for (int i=1; i<=4; i++) {
Mouse *mouse = [[Mouse alloc] init];
mouse.num = i;
[mouses addObject:mouse];
}
用瓶子的編碼的后4位的每一位分別代表每個老鼠是否喝此瓶水
for (UInt8 i=1; i<=waters.count; i++) {
UInt8 index1,index2,index3,index4;
// 取位
index1 = i & 1; // 第一個老鼠是否喝
index2 = i & 2; // 第二個老鼠是否喝
index3 = i & 4; // 第三個老鼠是否喝
index4 = i & 8; // 第四個老鼠是否喝
if (index1) {
[mouses[0] drinkWater:waters[i-1]];
}
if (index2) {
[mouses[1] drinkWater:waters[i-1]];
}
if (index3) {
[mouses[2] drinkWater:waters[i-1]];
}
if (index4) {
[mouses[3] drinkWater:waters[i-1]];
}
}
水已喝完,驗證一下是否找對有毒的瓶子
// 假設一天后
UInt8 number = 0; // 有毒的瓶子
for (UInt i=0; i<mouses.count; i++) {
NSLog(@"%@",mouses[i]);
UInt8 j = mouses[i].isLiving ? 0 : 1 << i;
number |= j;
}
NSLog(@"-------------------");
NSLog(@"有毒的瓶子編號是:%d",number);
打印如下
2018-11-22 17:08:42.042593+0800 Demo[1686:108521] 第10瓶有毒
2018-11-22 17:08:42.042883+0800 Demo[1686:108521] 1號老鼠未中毒
2018-11-22 17:08:42.042937+0800 Demo[1686:108521] 2號老鼠中毒
2018-11-22 17:08:42.042961+0800 Demo[1686:108521] 3號老鼠未中毒
2018-11-22 17:08:42.042974+0800 Demo[1686:108521] 4號老鼠中毒
2018-11-22 17:08:42.042983+0800 Demo[1686:108521] -------------------
2018-11-22 17:08:42.042999+0800 Demo[1686:108521] 有毒的瓶子編號是:10