爱因斯坦的超级问题(C++ code)

爱因斯坦的问题,以下是问题提示和C++的解决方案(老外写的) 供大家学习ING

下面的问题相信很多人都听过:
1 有五栋五种颜色的房子
2 每一位房子的主人国籍都不同
3 这五个人每人只喝一种饮料,只抽一种牌子的香烟,只养一种宠物
4 没有人有相同的宠物,抽相同牌子的香烟,喝相同的饮料
提示:
1、 英国人住在红房子里
2 、瑞典人养了一条狗
3 、丹麦人喝茶
4 、绿房子在白房子左边
5 、绿房子主人喝咖啡
6 、抽PALL MALL烟的人养了一只鸟
7 、黄房子主人抽DUNHILL烟
8 、住在中间那间房子的人喝牛奶
9 、挪威人住第一间房子
10 、抽混合烟的人住在养鱼人的旁边
11 、养马人住在DUNHILL烟的人旁边
12 、抽BLUE MASTER烟的人喝啤酒
13、 德国人抽PRINCE烟
14 、挪威人住在蓝房子旁边
15 、抽混合烟的人的邻居喝矿泉水
问题是:谁养鱼?

#include "Einstein.h"
#include <windows.h>

#define COUNT_SEARCHES 1
#define FILL_IN 1

CHouse CHint::house[COUNT_HOUSES];
CHouse* CHint::propowner[COUNT_CATEGORIES*COUNT_EXTENDED_CatID];
int CSolver::count_nodes = 0;
int CHint::count_solutions = 0;

// Array of pointers to CHint objects, i.e. a list of hints.
//
// I just keep the hint list in Einstein's order.
// Should you not want to be fooled by his
// tricky order, you could move the smiplest
// hints, hint 8 and hint 9 for example, to the
// top of the list so that the program searches
// fewer nodes.
//
CHint* CSolver::hint[] =
{
 // 1. the Brit lives in the red house
 new CSingleHouseHint(BRIT, RED),

 // 2. the Swede keeps dogs as pets
 new CSingleHouseHint(SWEDE, DOG),

 // 3. the Dane drinks tea
 new CSingleHouseHint(DANE, TEA),

 // 4. the green house is on the immediate left of the white house
 new COrderedNeighborsHint(GREEN, WHITE),
 
 // 5. the green house's owner drinks coffee
 new CSingleHouseHint(GREEN, COFFEE),

 // 6. the person who smokes Pall Mall rears birds
 new CSingleHouseHint(PALLMALL, BIRD),

 // 7. the owner of the yellow house smokes Dunhill
 new CSingleHouseHint(YELLOW, DUNHILL),

 // 8. the man living in the center house drinks milk
 new CKnownHouseHint(HOUSE2, MILK),

 // 9. the Norwegian lives in the first house
 new CKnownHouseHint(HOUSE0, NORWEGIAN),

 // 10. the man who smokes blends lives next to the one who keeps cats
 new CNeighborsHint(BLENDS, CAT),

 // 11. the man who keeps horses lives next to the man who smokes Dunhill
 new CNeighborsHint(HORSE, DUNHILL),

 // 12. the owner who smokes BlueMaster drinks beer
 new CSingleHouseHint(BLUEMASTER, BEER),

 // 13. the German smokes Prince
 new CSingleHouseHint(GERMAN, PRINCE),

 // 14. the Norwegian lives next to the blue house
 new CNeighborsHint(NORWEGIAN, BLUE),

 // 15. the man who smokes blends has a neighbor who drinks water
 new CNeighborsHint(BLENDS, WATER)
};


int __cdecl main(int argc, char* argv[])
{
 CSolver::DoTheWork();
 printf("Press any key to end the program ....");
 getch();
 return 0;
}

void CSolver::DoTheWork()
{
 __int64 start, finish, freq;

 PrintEinsteinRiddleDescription();
 QueryPerformanceFrequency((LARGE_INTEGER*) &freq);
 QueryPerformanceCounter((LARGE_INTEGER*) &start);
 for (int i = 0; i < COUNT_SEARCHES; i++)
  Search(&hint[0]); // start the engine with the first hint
 QueryPerformanceCounter((LARGE_INTEGER*) &finish);
 
 printf("/nProgram finished the exhaustive search of %d nodes in %.5f seconds and/n",
     GetNodeCount(), (double) (finish - start) / (double) freq);
 printf("found %d solution(s)./n/n", CHint::GetSolutionCount()/COUNT_SEARCHES);
}

void CSolver::PrintEinsteinRiddleDescription()
{
 // this is the problem decription
 static const char sRiddle[][75] =
 {
  "Einstein wrote a riddle last century. He said that 98% of the world could",
  "not solve it. ",
  "",
  "Einstein's riddle",
  "There are 5 houses in five different colors in a row.",
  "In each house lives a person with a different nationality. ",
  "The five owners drink a certain type of beverage, smoke a certain brand of",
  "cigar and keep a certain pet.",
  "No owners have the same pet, smoke the same brand of cigar or drink the",
  "same beverage.",
  "",
  "The question is: Who owns the fish?",
  "",
  "Einstein's hints:",
  " 1. The Brit lives in the red house",
  " 2. The Swede keeps dogs as pets",
  " 3. The Dane drinks tea",
  " 4. The green house is on the immediate left of the white house",
  " 5. The green house's owner drinks coffee",
  " 6. The person who smokes Pall Mall rears birds",
  " 7. The owner of the yellow house smokes Dunhill",
  " 8. The man living in the center house drinks milk",
  " 9. The Norwegian lives in the first house",
  "10. The man who smokes blends lives next to the one who keeps cats",
  "11. The man who keeps horses lives next to the one who smokes Dunhill",
  "12. The owner who smokes BlueMaster drinks beer",
  "13. The German smokes Prince",
  "14. The Norwegian lives next to the blue house",
  "15. The man who smokes blends has a neighbor who drinks water"
 };

 for (int i = 0; i < sizeof(sRiddle)/75; i++)
  puts(sRiddle[i]);
 puts("/n/nMachine's solution(s):/n");
}

void CSolver::Search(CHint** ppCHint)
{
 CHint* pCHint = *ppCHint;      // pointer to current hint
 
 IncNodeCount();         // increament node count
 pCHint->ResetSeekPosition();     // reset to start position

 while (pCHint->AssignPropToNextEligibles())  // seek and assign each eligibles
 {            // with properties.
  if (ppCHint != &hint[sizeof(hint)/sizeof(CHint*) - 1])  // is not the last
   Search(ppCHint + 1);     // search with next hint
  else          // all hints have been met
   CHint::PrintOut();      // a solution has been found
  pCHint->RemovePropFromPrevEligibles();  // undo the assign operations
 }
}

// remove property from the new owner if it exists
//
inline void CHint::RemoveProperty()
{
 if (m_pNewOwner0)
 {
  m_pNewOwner0->ClearProperty(m_pid0);
  RegisterOwnership(m_pid0, NULL);  // nobody owns m_pid0 now
 }
}

__forceinline int CHint::AssignPropertySetNextPos(CHouse* p0, CHouse* pNext)
{
 m_pNext = pNext;       // set next start for next seek
 if (p0 == NULL)        // m_pid0 has a owner alread
  m_pNewOwner0 = NULL;     // set no new owner flag
 else
 {
  m_pNewOwner0 = p0;      // keep the new owner for later recall
  p0->SetProperty(m_pid0);   
  RegisterOwnership(m_pid0, p0);   // p0 now has the title for m_pid0
 }
 return -1;
}
 
void CMultiPropertiesHint::RemovePropFromPrevEligibles()
{
 RemoveProperty();
 if (m_pNewOwner1)
 {
  m_pNewOwner1->ClearProperty(m_pid1);
  RegisterOwnership(m_pid1, NULL);   // nobody owns m_pid1 now
 }
}

__forceinline int CMultiPropertiesHint::AssignPropertiesSetNextPos(CHouse* p0,
                   CHouse* p1,
                   CHouse* pNext)
{
 AssignPropertySetNextPos(p0, pNext);
 if (p1 == NULL)        // m_pid1 has a owner alread
  m_pNewOwner1 = NULL;     // set no new owner flag
 else
 {
  m_pNewOwner1 = p1;      // keep the new owner for later recall
  p1->SetProperty(m_pid1);    
  RegisterOwnership(m_pid1, p1);   // p1 now has the title for m_pid1
 }
 return -1;
}

int CKnownHouseHint::AssignPropToNextEligibles()
{
 if (m_pNext == NULL)      // NULL is the stop sign
  return 0;

 CHouse* pOwner = GetPropertyOwner(m_pid0);

 if (pOwner)         // property m_pid0 has a owner already
 {
  if (pOwner == m_pKnownHouse)   // is it the required owner?
   return AssignPropertySetNextPos(NULL, NULL);
  return 0;
 }
 else if (m_pKnownHouse->IsEmpty(m_pid0))
  return AssignPropertySetNextPos(m_pKnownHouse, NULL);
 else
  return 0;
}

int COrderedNeighborsHint::AssignPropToNextEligibles()
{
 if (m_pNext >= &house[HOUSE4])  // &house[HOUSE4] acts as a stop sign:)
  return 0;

 CHouse* pOwner0 = GetPropertyOwner(m_pid0);
 CHouse* pOwner1 = GetPropertyOwner(m_pid1);

 if (pOwner0 && pOwner1)    // both m_pid0 and m_pid1 have owners already
 {
  if (pOwner1 == pOwner0 + 1)  // pOwner0 is on the immmeadiate left of pOwner1
   return AssignPropertiesSetNextPos(NULL, NULL, &house[HOUSE4]);
  return 0;
 }
 else if (pOwner0)     // pOwner1 == NULL; nobody owns m_pid1
 { 
  if (pOwner0 < &house[HOUSE4] && (pOwner0 + 1)->IsEmpty(m_pid1))
   return AssignPropertiesSetNextPos(NULL, pOwner0 + 1, &house[HOUSE4]);
  return 0;
 }
 else if (pOwner1)     // pOwner0 == NULL; nobody owns m_pid0
 {
  if (pOwner1 > &house[HOUSE0] && (pOwner1 - 1)->IsEmpty(m_pid0))
   return AssignPropertiesSetNextPos(pOwner1 - 1, NULL, &house[HOUSE4]);
  return 0;
 }
 else // pOwner0 == NULL && pOwner1 == NULL;  nobody owns m_pid0 or m_pid1
 {
  CHouse* p = m_pNext;
  
  while (p < &house[HOUSE4])
  {
   if (p->IsEmpty(m_pid0) && (p + 1)->IsEmpty(m_pid1))
    return AssignPropertiesSetNextPos(p, p + 1, p + 1);
   p++;
  }
  return 0;
 }
}

int CSingleHouseHint::AssignPropToNextEligibles()
{
 if (m_pNext >= &house[COUNT_HOUSES])  // &house[COUNT_HOUSES] acts as stop sign
  return 0;

 CHouse* pOwner0 = GetPropertyOwner(m_pid0);
 CHouse* pOwner1 = GetPropertyOwner(m_pid1);

 if (pOwner0 && pOwner1)
 {
  if (pOwner0 == pOwner1)  
   return AssignPropertiesSetNextPos(NULL, NULL, &house[COUNT_HOUSES]);
  return 0;
 }
 else if (pOwner0)       // pOwner1 == NULL; nobody owns m_pid1
 {
  if (pOwner0->IsEmpty(m_pid1))
   return AssignPropertiesSetNextPos(NULL, pOwner0, &house[COUNT_HOUSES]);
  return 0;        // failed
 }
 else if (pOwner1)       // pOwner0 == NULL; nobody owns m_pid0
 {
  if (pOwner1->IsEmpty(m_pid0))
   return AssignPropertiesSetNextPos(pOwner1, NULL, &house[COUNT_HOUSES]);
  return 0;
 }
 else // pOwner0 == NULL && pOwner1 == NULL;  nobody owns m_pid0 or m_pid1
 {
  CHouse* p = m_pNext;
 
  while (p < &house[COUNT_HOUSES])
  {
   if (p->IsEmpty(m_pid0) && p->IsEmpty(m_pid1))
    return AssignPropertiesSetNextPos(p, p, p + 1);
   p++;
  }
  return 0;
 }
}

int CNeighborsHint::AssignPropToNextEligibles()
{
 if (m_pNext >= &house[HOUSE4])    // &house[HOUSE4] acts as stop sign
  return 0;

 CHouse* pOwner0 = GetPropertyOwner(m_pid0);
 CHouse* pOwner1 = GetPropertyOwner(m_pid1);

 if (pOwner0 && pOwner1)
 {
  if (pOwner0 - pOwner1 == 1 || pOwner0 - pOwner1 == -1)  
   return AssignPropertiesSetNextPos(NULL, NULL, &house[HOUSE4]);
  return 0;
 }
 else if (pOwner0)       // pOwner1 == NULL; nobody owns m_pid1
 {
  if (!m_NextReverse && pOwner0 < &house[HOUSE4] && (pOwner0 + 1)->IsEmpty(m_pid1))
  {
   m_NextReverse = -1;
   return AssignPropertiesSetNextPos(NULL, pOwner0 + 1, pOwner0);
  }
  if (pOwner0 > &house[HOUSE0] && (pOwner0 - 1)->IsEmpty(m_pid1))
   return AssignPropertiesSetNextPos(NULL, pOwner0 - 1, &house[HOUSE4]);
  return 0;
 }
 else if (pOwner1)       // pOwner0 == NULL; nobody owns m_pid0
 {
  if (!m_NextReverse && pOwner1 < &house[HOUSE4] && (pOwner1 + 1)->IsEmpty(m_pid0))
  {
   m_NextReverse = -1;
   return AssignPropertiesSetNextPos(pOwner1 + 1, NULL, pOwner1);
  }
  if (pOwner1 > &house[HOUSE0] && (pOwner1 - 1)->IsEmpty(m_pid0))
   return AssignPropertiesSetNextPos(pOwner1 - 1, NULL, &house[HOUSE4]);
  return 0;
 }
 else      // pOwner0 == NULL && pOwner1 == NULL
 {
  CHouse* p = m_pNext;
 
  while (p < &house[HOUSE4])
  {
   if (!m_NextReverse && p->IsEmpty(m_pid0) && (p + 1)->IsEmpty(m_pid1))
   {
    m_NextReverse = -1;
    return AssignPropertiesSetNextPos(p, p + 1, p);
   }
   if (p->IsEmpty(m_pid1) && (p + 1)->IsEmpty(m_pid0))
   {
    m_NextReverse = 0;
    return AssignPropertiesSetNextPos(p + 1, p, p + 2);
   }
   p += 2;
  }
  return 0;
 }
}

// This function is to verify current solution and is to be called whenever a
// solution is found.
//
// return:
//   NULL: failed for search error(s).
//   nonzero: pointer to the owner of the fish
//
CHouse* CHint::VerifyCurrentSolution()
{
 CHouse* pFishOwner = NULL;

 for (int i = 0; i < COUNT_HOUSES; i++)
 {
  if (house[i].IsEmpty(COLOR) || house[i].IsEmpty(NATIONALITY) ||
   house[i].IsEmpty(BAVERAGE) || house[i].IsEmpty(CIGAR)
   )
   return NULL;

  if (house[i].IsEmpty(PET))
   if (pFishOwner)
    return NULL;
   else
    pFishOwner = &house[i];
 }
 return pFishOwner;
}

// This interface function verifies and prints out the current solution
//
void CHint::PrintOut()
{
 IncSolutionCount();     // the solution is valid
#if FILL_IN > 0
 CHouse* pFishOwner = VerifyCurrentSolution();

 if (pFishOwner == NULL)
 {
  puts("found a search error./n");
  return;
 }
 // we have also to fill in the fish before sending a solution solution to
 // the screen because Einstein did not mention it in his hints.
 //
 pFishOwner->SetProperty(FISH);
#endif 

 printout();

#if FILL_IN > 0
 pFishOwner->ClearProperty(FISH); // restore the world for further search
#endif
}

// Print a solution on console screen
// Some of the drawing code in this function was borrowed from Manfred Becker's.
//
void CHint::printout()
{
 static const char sColor[][7 + 1] =
 {
  "  blue ", "  green", "   red ", "  white", " yellow"
 };
 static const char sNationality[][9 + 1] =
 {
  "  Brit   ", "  Dane   ", " German  ", "Norwegian", "  Swede  "
 };
 static const char sBaverage[][7 + 1] =
 {
  "  Beer ", " Coffee", "  Milk ",  "   Tea ", "  Water"
 };
 static const char sCigar[][9 + 1] =
 {
  " Blends  ", "BlueMastr", " Dunhill ", "Pall Mall", " Prince  " };
 static const char sPet[][7 + 1] =
 {
  "  Bird ", "   Cat ", "   Dog ", "  Fish ", "  Horse"
 };

 static const char sWild7[] =  "   *   ";
 static const char sWild9[] = "    *    ";

 static char sln[][79] =
 {
  "     / //            / //            / //            / //            / //",
  "    /   //          /   //          /   //          /   //          /   //",
  "   /  1  //        /  2  //        /  3  //        /  4  //        /  5  //",
  "  /       //      /       //      /       //      /       //      /       //",
  " /         //    /         //    /         //    /         //    /         // ",
  "/___________//  /___________//  /___________//  /___________//  /___________//",
  "|           |  |           |  |           |  |           |  |           |",
  "|           |  |           |  |           |  |           |  |           |",
  "|           |  |           |  |           |  |           |  |           |",
  "|           |  |           |  |           |  |           |  |           |",
  "|           |  |           |  |           |  |           |  |           |",
  "|___________|  |___________|  |___________|  |___________|  |___________|"
 };

 // Print houses...
 int i;
 for (i = 0; i < COUNT_HOUSES; i++)
 {
  memcpy(&sln[4][2 + 15*i], house[i].IsEmpty(COLOR) ? sWild7 : sColor[house[i].GetPropIndex(COLOR)], 7);
  memcpy(&sln[7][2 + 15*i], house[i].IsEmpty(NATIONALITY) ? sWild9 : sNationality[house[i].GetPropIndex(NATIONALITY)], 9);
  memcpy(&sln[8][2 + 15*i], house[i].IsEmpty(BAVERAGE) ? sWild7 : sBaverage[house[i].GetPropIndex(BAVERAGE)], 7);
  memcpy(&sln[9][2 + 15*i], house[i].IsEmpty(CIGAR) ? sWild9 : sCigar[house[i].GetPropIndex(CIGAR)], 9);
  memcpy(&sln[10][2 + 15*i], house[i].IsEmpty(PET) ? sWild7 : sPet[house[i].GetPropIndex(PET)], 7);
 }

 for (i = 0; i < sizeof(sln)/79; i++)
  puts(sln[i]);
 puts("/n");
}

以下是头文件内容:

#include <iostream>
#include <conio.h>
#include <time.h>

enum Problem_Constants
{
 COUNT_HOUSES = 5,
    COUNT_CATEGORIES = 5,
// COUNT_HINTS = 15,
 BITS_CatID = 3,
 COUNT_EXTENDED_CatID = 1 << BITS_CatID   //  COUNT_EXTENDED_CatID = 8
};

// Property Category ID
enum CatID
{
 COLOR,
 NATIONALITY,
 BAVERAGE,
 CIGAR,
 PET
};

// Property Identifications
enum PropID
{
 BLUE       = (0 << BITS_CatID) | COLOR, 
 GREEN      = (1 << BITS_CatID) | COLOR,  
 RED        = (2 << BITS_CatID) | COLOR,     
 WHITE      = (3 << BITS_CatID) | COLOR,    
 YELLOW     = (4 << BITS_CatID) | COLOR,

 BRIT    = (0 << BITS_CatID) | NATIONALITY,  
 DANE       = (1 << BITS_CatID) | NATIONALITY,       
 GERMAN     = (2 << BITS_CatID) | NATIONALITY,  
 NORWEGIAN  = (3 << BITS_CatID) | NATIONALITY,
 SWEDE      = (4 << BITS_CatID) | NATIONALITY, 


 BEER       = (0 << BITS_CatID) | BAVERAGE,
 COFFEE     = (1 << BITS_CatID) | BAVERAGE,
 MILK    = (2 << BITS_CatID) | BAVERAGE,
 TEA     = (3 << BITS_CatID) | BAVERAGE,
 WATER    = (4 << BITS_CatID) | BAVERAGE,

 BLENDS     = (0 << BITS_CatID) | CIGAR,
 BLUEMASTER = (1 << BITS_CatID) | CIGAR,
 DUNHILL    = (2 << BITS_CatID) | CIGAR,
 PALLMALL   = (3 << BITS_CatID) | CIGAR,
 PRINCE    = (4 << BITS_CatID) | CIGAR,

 BIRD    = (0 << BITS_CatID) | PET,
 CAT        = (1 << BITS_CatID) | PET,
 DOG     = (2 << BITS_CatID) | PET,
 FISH    = (3 << BITS_CatID) | PET,
 HORSE    = (4 << BITS_CatID) | PET
};


enum HouseID
{
 HOUSE0, HOUSE1, HOUSE2, HOUSE3, HOUSE4
};


class CHouse
{
private:
 enum
 { 
  // EMPTY is a flag to indicate a null property of any category.
  // Its value must not be equal to any real property (any element of PropID).
  EMPTY  = (0 << BITS_CatID) | PET + 1
 };

 PropID m_property[COUNT_CATEGORIES];


// constructor
public:
 CHouse()
 {
  for (int i = 0; i < COUNT_CATEGORIES; i++)
   m_property[i] = (PropID) EMPTY;
 }

// operations
public:
 int IsEmpty(CatID cid)   { return m_property[cid] == EMPTY; }
 int IsEmpty(PropID pid)   { return IsEmpty(GetCatID(pid)); }
 int GetPropIndex(CatID cid)  { return GetIndex(m_property[cid]); }
 void SetProperty(PropID pid) { m_property[GetCatID(pid)] = pid; }
 void ClearProperty(PropID pid) { m_property[GetCatID(pid)] = (PropID) EMPTY;}

private:
 CatID GetCatID(PropID pid) { return (CatID) (pid & (COUNT_EXTENDED_CatID - 1)); }
 int GetIndex(PropID pid)   { return pid >> BITS_CatID; }
};

class CHint
{
protected:
 const PropID m_pid0; // a property in the hint
 CHouse* m_pNewOwner0; // ptr to a would-be owner of the property to meet the hint
 CHouse* m_pNext;  // the next house to be checked and filled

 static CHouse house[COUNT_HOUSES];    // array of the houses
private:
 // array of pointers to house owners indexed by PropID
 static CHouse* propowner[COUNT_CATEGORIES*COUNT_EXTENDED_CatID];
 static int count_solutions;      // count of solutions found

// constructor
protected:
 CHint(PropID pid0) : m_pid0(pid0) {}

public:
 // starting from house specified by m_pNext, seek and assign the
 // first eligible houseowner(s) with properties.
 //
 // return value:
 //   0 : failed 
 // nonzero : successful
 //
 virtual int AssignPropToNextEligibles() = 0; 
 
 virtual void RemovePropFromPrevEligibles() = 0; // undo AssignPropToNextEligibles
 virtual void ResetSeekPosition() = 0;   // reset the seek to start position
 static  void PrintOut();      // print out a solution

// helpers
protected:
 void RemoveProperty();       // remove property from new owner
 int AssignPropertySetNextPos(CHouse* p0, CHouse* pNext);

// property register operations
protected:
 static CHouse* GetPropertyOwner(PropID pid) { return propowner[pid]; }
 static void RegisterOwnership(PropID pid, CHouse* pOwner)
 { 
  propowner[pid] = pOwner;
 }

// counter
public:
 static int GetSolutionCount()  { return count_solutions; };
private:
 static void IncSolutionCount() { count_solutions++; };

// helper
 static CHouse*  VerifyCurrentSolution();    // verify a solution and check for errors
 static void printout();
};

// class for any hint of Known house number
//
class CKnownHouseHint : public CHint
{
private:
 CHouse* const m_pKnownHouse;

public:
 CKnownHouseHint(HouseID i, PropID pid) : CHint(pid), m_pKnownHouse(&house[i]) {}

private:
 virtual int AssignPropToNextEligibles(); 
 virtual void ResetSeekPosition()     { m_pNext = m_pKnownHouse; }
 virtual void RemovePropFromPrevEligibles() { RemoveProperty(); }
};

// class for any hint that involves Multiple properties
//
class CMultiPropertiesHint : public CHint
{
protected:
 const PropID m_pid1; // a property in the hint
 CHouse* m_pNewOwner1; // ptr to a would-be owner of the property to meet the hint

// implementations
protected:
 virtual void RemovePropFromPrevEligibles();

// constructor
protected:
 CMultiPropertiesHint(PropID pid0, PropID pid1) : CHint(pid0), m_pid1(pid1) { }

// helpers
protected:
 void ResetSeekPositionToFirstHouse() { m_pNext = &house[HOUSE0]; }
 int AssignPropertiesSetNextPos(CHouse* p0, CHouse* p1, CHouse* pNext);
};

// class for the any hint that only involves a Single houseowner
//
class CSingleHouseHint : public CMultiPropertiesHint
{
// constructor
public:
 CSingleHouseHint(PropID pid0, PropID pid1) : CMultiPropertiesHint(pid0, pid1) { }

// implementations
private:
 virtual int AssignPropToNextEligibles(); 
 virtual void ResetSeekPosition() { ResetSeekPositionToFirstHouse(); }
};

// class for any hint that involves 2 Neighbors Ordered by direction
//
class COrderedNeighborsHint : public CMultiPropertiesHint
{
// constructor
public:
 COrderedNeighborsHint(PropID pid0, PropID pid1) : CMultiPropertiesHint(pid0, pid1) {}

// implementations
private:
 virtual int AssignPropToNextEligibles(); 
 virtual void ResetSeekPosition() { ResetSeekPositionToFirstHouse(); }
};

// class for any hint that involves 2 Neighbors without a directional restriction
//
class CNeighborsHint : public CMultiPropertiesHint
{
private:
 int m_NextReverse;   // are the properties to be filled in reverse order?

// constructor
public:
 CNeighborsHint(PropID pid0, PropID pid1) : CMultiPropertiesHint(pid0, pid1) { }

// implementations
private:
 virtual int AssignPropToNextEligibles(); 
 virtual void ResetSeekPosition()  
 {
  ResetSeekPositionToFirstHouse();
  m_NextReverse = 0;
 }
};

// class for finding the solutions
//
class CSolver
{
private:
 static CHint* hint[];       // array of pointers to CHint objects
 static int count_nodes;       // count of nodes searched

// operations
public:
 static void DoTheWork();      // search driver

// helpers
private:
 static void Search(CHint** ppCHint);   // search engine
 static void PrintEinsteinRiddleDescription();
 static void IncNodeCount()    { count_nodes++; };
 static int GetNodeCount()    { return count_nodes; };
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值