亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 01.cpp

?? 這是一個九宮圖游戲,可自動生成也可手動生成初始狀態,有過程演示!
?? CPP
字號:
//#ifndef EIGHTNUM_H_
//#define EIGHTNUM_H_

#include <iostream>
#include <ctime>
#include <string>
#include <windows.h>
using namespace std;


const int MAX = 9;
extern char target[MAX +1] ;
extern char joinArr[362880] ;


//節點定義.
class Qnode 
{
public:
    char *data;
    Qnode *next;
    int parentnum;
    Qnode();
    Qnode( const char * );
    Qnode( const Qnode & );
    Qnode& operator=( const Qnode & );
    bool operator==( Qnode & );
    bool IsJoined();
    bool HaveSolution();
    bool Goal()const;
    //friend ostream &operator<<( ostream &, char* );
};


//以節點組成的對列.
class Queen
{
public:
    int length;
    Qnode* head;
    Qnode* tail;
    Queen();
    Queen( const Queen &);
    Queen& operator=( const Queen &);
    bool Empty()const;
    void Back_insert( Qnode& );
    void Front_delete();
    Qnode GetFirNode();
};

/**//*全局函數*/

extern Qnode qq[362880] ;            //所有節點的狀態數組.
bool Move(char*, int );                //把某個狀態進行4個方向的移動.
void Calculate( char* p );            //本題的關鍵函數.用于實現八數碼的擴展數組.
int Fac(int n);                        //遞歸函數
int SmallerNum(char *p, int index);
bool IsJoined(char *oldState);        //實現判斷一個狀態是否已經加入OPEN表
void GetFinalpath(Qnode *, int);    //獲得最優路徑

//#endif



char target[MAX +1] = "123804765" ;  // 自定義的目標狀態.
char joinArr[362880] ={0};     // 判斷所有狀態的數組.
Qnode qq[362880];      //節點的數組,存放所有已經擴展的不重復的節點.

/******** 節點類的實現函數  *********/

Qnode::Qnode()
{
 parentnum = -1;
 next = NULL;
 data = new char[MAX];
 data[MAX] = '\0';
}

Qnode::Qnode( const char * p)
{
 parentnum = -1;
 this->next = NULL;
 data = new char[MAX];
 strcpy( data,p);
}

/*拷貝構造函數*/
Qnode::Qnode( const Qnode& node )
{
 parentnum = node.parentnum;
 data = new char[MAX];
 strcpy( data,node.data);
 this->next = NULL;
}

/*賦值重載*/
Qnode& Qnode::operator=( const Qnode & node)
{ 
 parentnum = node.parentnum;
 data = new char[MAX];
 strcpy( data,node.data);
 this->next = NULL;
 return *this;

}

/*判斷一個狀態是否為目標狀態*/
bool Qnode::Goal()const
{
 if (strcmp(data, target)!=0)
  return false;
 else
  return true;
}

/*判斷一個狀態和另外一個狀態是否相同*/
bool Qnode::operator ==( Qnode & node )
{
 for( int i = 0 ;i < MAX; i++ )
 {
  if( node.data[i] != this->data[i])
   return false;
 }
 return true;
}
/****************************************************

利用奇偶性判斷所給出的初始狀態有無解.

判別方法是:
以數組為一維的舉例子.
將八數碼的一個結點表示成一個數組a[9],空格用0表示,設臨時函數p(x)定義為:x數所在位置前面的數比x小的數的個數,
其中0空格不算在之內,那設目標狀態為b[9],那r=sigma(p(x)) sigma()表示取所有的x:1-8并求和,
那對于初始狀態a[9],t=sigma(p(x)),如果r和t同為奇數或者同為偶數,那么該狀態有解,否則無解。

考慮到四種移動方法對sigma(p(x))的影響,左移和右移是不會影響它的值的,
更不會影響奇偶性,如果是上移或者下移就會影響:
上移:一次上移會使一個元素向前跳兩個數字的位置,設這兩個數字為a1,a2,
不妨設a1<a2,移的這個數字設為a0,那無非只有以下三次情況:
1,a0<a1<a2,考慮它們三者的p(x)值,p(a0)不變,p(a1)++,p(a2)++,總體增加了2
2,a1<a0<a2,p(a0)--,p(a1)不變,p(a2)++,總體不變
3,a1<a2<a0,p(a0)-=2,p(a1),p(a2)不變,總體減小了2

綜合起來的結論就是不會影響sigma(p(x))的奇偶性。
*****************************************************/

bool Qnode::HaveSolution( )
{
 int i,j,sum2 = 0,sum1 = 0;
 for( i = 0; i< MAX; i++ )
  for( j = 0; j < i; j++ )
  {
   if(( this->data[i] - 48) * (this->data[j] - 48))
   {
    if( this->data[j] < this->data[i] )
    sum1++;
   }
  }
 for( i = 0; i< MAX; i++ )
  for( j = 0; j < i; j++ )
  {
   if( (target[i] - 48) * ( target[j] - 48 ) )
   {
    if( target[j] < target[i] )
    sum2++;
   }
  }

 if( sum1 % 2 == sum2 % 2 )
  return true;
  return false;
}

/*打印某個節點,用操作符重載*/
/*ostream &operator<<( ostream & os, char *p)
{
 int i,cnt = 0;
 for( i = 0; i != MAX; i++)
 {
  os << p[i] << " ";
  cnt++;
  if(cnt == 3)
  {
   os <<endl;
   cnt = 0;
  }
 }
 os << endl;
 return os;
}*/

/**********隊列類的實現***********/


Queen ::Queen()
{
 length = 0;
 head = tail = NULL;
}

Queen::Queen( const Queen & queen )
{
 length = queen.length;
 Qnode *head = new Qnode;
 Qnode *tail = new Qnode;
 head = queen.head;
 tail = queen.tail;
 Qnode temp;
 while( !(temp.operator ==( *tail ) ) )
 {
  Qnode *newptr = new Qnode;
 }

}

Queen & Queen::operator=( const Queen & queen )
{
 length = queen.length;
 Qnode *head = new Qnode;
 Qnode *tail = new Qnode;
 head = queen.head;
 tail = queen.tail;
 Qnode temp;
 while( !(temp.operator ==( *tail ) ) )
 {
  Qnode *newptr = new Qnode;
 }
 return *this;
}

/*尾部插入*/
void Queen::Back_insert( Qnode& Qnode )
{
 if(head == NULL)
 {
  Qnode.next = NULL;
  head = tail = &Qnode;
  tail->next =  NULL;
  length++;
 }
 else
 {
  Qnode.next = NULL;
  tail->next = &Qnode;
  tail = &Qnode;
  length++;
 }
}

/*首刪除*/
void Queen::Front_delete()
{
 if(!Empty())
 {
  Qnode * temp;
  temp = head;
  head = head->next;
  length--;
  //delete temp;????
 }
}

Qnode Queen::GetFirNode()
{
 if(!Empty())
 {
  return *(this->head) ;
 }
 else
  return NULL;
}

/* 判斷隊列是否為空.*/
bool Queen::Empty()const
{
 if( length == 0 )
  return true;
 return false;
}

/*打印節點*/
/*ostream &operator<<( ostream & os, const Qnode & Qnode )
{
 for( int i = 0; i< MAX; i++ )
  os << Qnode.data[i] << " ";
 return os;
}*/

/******其他的小函數.********/

/**********************************************

通過求出p數組中0的位置送給x,y,然后根據給定的m(移動方向)
0上,1下,2左,3右.然后綜合兩個變量,來判斷是否可行.

**********************************************/

bool Move(char* p, int m)
{
 int x = 0,y = 0;
 char temp;
 for( int i = 0; i< MAX; i++)
  if( p[i] == '0' )
  {
   x = i / 3;
   y = i % 3;
  }
 if     ( m == 0 && x == 0 ) return false;
 else if( m == 1 && x == 2 ) return false;
 else if( m == 2 && y == 0 ) return false;
 else if( m == 3 && y == 2 ) return false;
 else    
 {

  switch(m)
  {
   case 0: //上移一步。
     temp = p[(x-1) * 3 + y];
     p[ x * 3 + y ] = temp;
     p[ (x-1) * 3 + y ] = '0';
     break;
    
   case 1://下移一步
     temp = p[(x+1) * 3 + y];
     p[ x * 3 + y ] = temp;
     p[ (x+1) * 3 + y ] = '0';
     break;
   
   case 2://左移一步
     temp = p[x * 3 + y - 1];
     p[ x * 3 + y ] = temp;
     p[ x * 3 + y - 1] = '0';
     break;
    
   case 3://右移一步
   
     temp = p[x * 3 + y + 1];
     p[ x * 3 + y ] = temp;
     p[ x * 3 + y + 1] = '0';
     break;
    
  }
  return true;
 }
  
}

bool IsJoined(char *oldState)
{
 int i;
 int index = 0;
 int base = MAX;
 char newState[MAX+1];
 strcpy(newState, oldState);
 for(i=0; newState[i]!='0';i++);
 newState[i] = '9';
 index += (newState[0]- '0' -1) * Fac(base-1);
 for (i=1; i!=base; i++)
 {
  index += Fac(base-1-i) * (newState[i] - '0' - 1 - SmallerNum(newState, i));
 }
 //如果newState已經加入則返回真
 //cout << index << endl;
 if (joinArr[index] == '1')
 {
  return true;
 }
 //否則將對應狀態改為1,表示將當前狀態加入
 joinArr[index] = '1';
 return false;
}

int Fac(int n)
{
 if (n==0 || n==1)
 {
  return 1;
 }
 return n * Fac(n-1);
}

int SmallerNum(char *p,int index)
{  
 int sum = 0; 
 for (int i=0; i!=index; i++)
 {
  if (p[i] < p[index])
  {
   sum++;
  }
 }
 return sum;
}

void GetFinalpath(Qnode *scanArr,int lastIndex)
{
 int index = 0;
 int wrap = 0;
 int parentID = scanArr[lastIndex].parentnum;
 string path[50];
 path[index++] = string(scanArr[lastIndex].data);
 while (scanArr[parentID].parentnum != -1)
 {
  path[index++] = string(scanArr[parentID].data);
  parentID = scanArr[parentID].parentnum;
 }
 path[index] = string(scanArr[0].data);
 int i = 0,j = index;
 string temp;
 while( i < j )
 {
  temp = path[i];
  path[i] = path[j];
  path[j] = temp;
  i++;j--;
 }
 int count = index + 1;
 int group = count / 8;
 int row = group * 3;
 int temp1 = 0;

 /***************打印分組類似于下面的圖形**************************************

 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 

 *************************************************************/

 ////////先打印每行都是滿8個的/////////
 for(  i = 0; i != group ; i++ )
 {
  //分成行數,在組的基礎上每組分三行.
  for( int j = 0; j != 3; j++ )
  {
   //每行分成八部分.
   for( int k = 0; k != 8; k++ )
   {
    int r = 0;
    cout << path[i*8+k][3*j+r] << " ";
    r++;
    cout << path[i*8+k][3*j+r] << " ";
    r++;
    cout << path[i*8+k][3*j+r] << '\t' ;
   }
   cout << endl;
  }
  cout << endl ;
  temp1 = i + 1;
 }

 ///////////////打印每行不滿8個的/////////////
 if(count % 8 != 0)
 {
  for( int j = 0; j != 3; j++ )
   {
    //每行分成四部分.
    for( int k = 0; k != index + 1 - temp1 * 8; k++ )
    {
     int r = 0;
     cout << path[temp1*8+k][3*j+r] << " ";
     r++;
     cout << path[temp1*8+k][3*j+r] << " ";
     r++;
     cout << path[temp1*8+k][3*j+r] << '\t' ;
    }
    cout << endl;
   }
  cout << endl ;
 }
 cout << "從初始狀態到目標狀態最優路徑要經過 "<< index+1 << "個節點."<< endl;
 cout << "按回車,開始動態演示.動態顯示節點運行情況,請注意好0點的運作." << endl;
 cin.get();
 cin.get();
 system("cls");
 for( int p = 0; p <= index ; p++)
 {
  cout << endl << endl<< endl << endl<< endl << endl<< endl ;
  cout << "\t\t\t\t";
  for( int i = 0; i < 9; i++)
  {
   if(path[p][i] != '0')
   {
    cout << path[p][i] << "\t";
   }
   else
   {
    cout << " " << "\t";
   }
   if( (i+1) % 3 == 0)
   { 
    cout << endl<< endl<< endl<< endl;
    cout << "\t\t\t\t";
   }
  }
  Sleep(1000);
  if(p != index )
  {
   system("cls");
  }
 }
 cout <<  "\t演示結束,謝謝觀看." << endl;
 cin.get();
 cin.get();

}


/*本算法的核心*/
/*******************************************************

 寬度優先搜索算法如下: 
  (1) 把起始節點放到OPEN表中(如果該起始節點為一目標節點,則求得一個解答)。
  (2) 如果OPEN是個空表,則沒有解,失敗退出;否則繼續。
  (3) 把第一個節點(節點n)從OPEN表移出,并把它放入CLOSED(qq數組中)擴展節點表中。
  (4) 擴展節點n。如果沒有后繼節點,則轉向上述第(2)步。
  (5) 把n的所有后繼節點放到OPEN表的末端,并提供從這些后繼節點回到n的指針。
  (6) 如果n的任一個后繼節點是個目標節點,則找到一個解答,成功退出;否則轉向第(2)步。

*******************************************************/

void Calculate( char* ptr )
{
 clock_t startTime;
 clock_t endTime;
 startTime = clock();

 int i,k = 0,cnt = 0;
 Qnode qnode(ptr);
 Queen queen;
 if( !IsJoined( qnode.data ) )
 {
  queen.Back_insert(qnode);
  qq[k++] = qnode;
 }
 Qnode Qhead;
 Qnode *tmp;
 while( queen.length)
 {
  strcpy(Qhead.data,(*queen.head).data);
  for( i = 0; i< 4; i++ )
  {
   tmp = new Qnode(Qhead);
   if( Move( (*tmp).data, i ) )
   {
    if( tmp->Goal())
    {
     (*tmp).parentnum = cnt;
     qq[k] = (*tmp);
     endTime = clock();
     cout << "整個八數碼尋找最優路徑耗時 " << static_cast<long>(endTime - startTime) << "毫秒..." << endl;
     GetFinalpath(qq,k);
     return;
    }
    else 
    {
     if( !IsJoined( (*tmp).data ) )
     {
      queen.Back_insert( *tmp);
      (*tmp).parentnum = cnt;
      qq[k++] = (*tmp);
     }
    }
   }
   else
   {
    delete tmp;
   }
  }
  queen.Front_delete();
  cnt++;
 }
}
extern int a = 4;
int main(void)
{
 int i;
 Qnode node;
 char choice;
 string str;
 cout << "\t\t\t\tthe second evrsion." << endl;
 cout << "請選擇初始化方式:\n\ta: 手動初始化.\n\tb:自動初始化." << endl;
 cout << "您的選擇是:";
 cin >> choice;
 if( choice == 'a' )
 {
  cout << "輸入9個空格中所填寫的數字(連續輸入數字,回車結束.)." << endl;
  cin >> str;
  for( i = 0; i < 9; i++)
   node.data[i] =  str[i];
  node.data[9] = '\0';
 }
 else
 {
  srand((unsigned)time(0));
  for( i = 0; i < MAX; i++)
    node.data[i] = i + 48;
  node.data[MAX] = '\0';
  for( int i = 0; i < 20 ;i++ )
  {
   int m = rand() % 9;
   int n = rand() % 9;
   char temp = node.data[m];
   node.data[m] = node.data[n];
   node.data[n] = temp;
  }
 }
 cout << "初始狀態是:" << endl;
 cout << node.data;
 cout << "請確認您是否要修改默認目標狀態.?修改(y,Y),否(n,N) " << endl;
  cin >> choice;
 if( choice == 'y' || choice == 'Y')
 {
  cout << "請輸入您要的目標狀態." << endl;
  cin >> str;
  for( i = 0; i < MAX; i++)
   target[i] =  str[i];
  
 }
 cout << "打印目標狀態:" << endl;
 cout << target;
 // 判斷是否能夠達到目標節點.
 if( !node.HaveSolution( ))
  cerr << "this puzzle is not solvable." << endl;
 else
  Calculate(node.data);
 cout << endl;
 return 0;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
色综合欧美在线| 国产午夜精品久久久久久免费视 | 欧美色图一区二区三区| 日韩欧美一卡二卡| 蜜臀av亚洲一区中文字幕| 99精品视频一区| 久久影音资源网| 午夜亚洲福利老司机| 成人精品电影在线观看| 日韩一级成人av| 一区二区三区四区在线| 国产91对白在线观看九色| 日韩亚洲电影在线| 午夜精品aaa| 日本精品一区二区三区四区的功能| 精品美女一区二区三区| 亚洲成人免费观看| 在线观看亚洲精品视频| 中文字幕一区二区三区不卡在线| 极品少妇xxxx偷拍精品少妇| 欧美日韩精品高清| 亚洲国产精品天堂| 欧美在线free| 有坂深雪av一区二区精品| 成人免费av在线| 国产视频一区二区在线| 国产一区二区美女| 久久久www免费人成精品| 国内精品不卡在线| 亚洲小少妇裸体bbw| 色欧美乱欧美15图片| 亚洲人成网站精品片在线观看| 成人免费高清在线| 国产精品美女久久久久久久久久久| 国产一区二区影院| 久久午夜老司机| 国产a精品视频| 国产精品美女久久久久aⅴ国产馆| 盗摄精品av一区二区三区| 欧美经典一区二区三区| 国产成人在线免费观看| 日韩理论片一区二区| 色久综合一二码| 视频一区二区三区在线| 精品国产一区二区国模嫣然| 久久69国产一区二区蜜臀| 精品盗摄一区二区三区| 国产精品1024| 中文字幕亚洲区| 欧美日韩黄视频| 日韩精品一级中文字幕精品视频免费观看 | 欧美精品1区2区| 九色|91porny| 中文字幕制服丝袜成人av| 91免费看片在线观看| 一级日本不卡的影视| 欧美一级片免费看| 国产美女av一区二区三区| 亚洲欧洲成人精品av97| 欧美伊人久久久久久久久影院| 亚洲va中文字幕| 久久久久久久久久美女| 色婷婷av一区二区三区之一色屋| 日韩电影在线观看一区| 久久久精品天堂| 欧美在线视频日韩| 国产激情一区二区三区四区 | 久久精品一区二区三区不卡| 91在线观看视频| 另类调教123区| 中文字幕一区在线| 91精品免费在线| voyeur盗摄精品| 免费观看成人av| 亚洲欧美激情插| 精品理论电影在线观看| 色婷婷综合久久| 国产一区二区视频在线播放| 亚洲综合色视频| 日本一区二区在线不卡| 91精品国产91久久久久久一区二区 | 亚洲国产日韩一级| 欧美激情综合五月色丁香小说| 欧美日韩成人一区| av成人免费在线| 狠狠色伊人亚洲综合成人| 国产精品 欧美精品| 肉丝袜脚交视频一区二区| |精品福利一区二区三区| 日韩欧美国产电影| 色8久久人人97超碰香蕉987| 国产成人精品1024| 蜜桃av噜噜一区| 五月天欧美精品| 亚洲免费在线观看| 国产精品嫩草影院com| 久久综合九色欧美综合狠狠| 91.成人天堂一区| 欧日韩精品视频| 91丨porny丨户外露出| 国产精品亚洲第一| 韩国av一区二区三区在线观看| 石原莉奈一区二区三区在线观看| 一区二区三区在线免费播放| 亚洲欧洲无码一区二区三区| 亚洲国产精品二十页| 久久久蜜桃精品| 久久久综合激的五月天| 精品国产露脸精彩对白| 日韩免费福利电影在线观看| 91精品国产综合久久蜜臀| 欧洲中文字幕精品| 欧美日韩免费不卡视频一区二区三区| av网站一区二区三区| 成人av集中营| 91日韩在线专区| 91热门视频在线观看| 91浏览器打开| 欧美日韩亚洲国产综合| 欧美日韩另类一区| 91.麻豆视频| 欧美精品一区二区久久婷婷| 久久综合久久综合久久| 国产亚洲人成网站| 国产欧美视频一区二区| 中文文精品字幕一区二区| 国产精品久久久久久久久免费樱桃| 欧美国产日韩在线观看| 亚洲品质自拍视频网站| 一区二区久久久| 无吗不卡中文字幕| 精品午夜久久福利影院| 高清久久久久久| 91国内精品野花午夜精品| 欧美高清精品3d| 久久影视一区二区| 日韩一区中文字幕| 偷偷要91色婷婷| 精品一区二区综合| 91亚洲午夜精品久久久久久| 欧美人妖巨大在线| 337p日本欧洲亚洲大胆色噜噜| 国产日本亚洲高清| 一区二区三区欧美日| 麻豆成人久久精品二区三区小说| 国产精品一级片在线观看| 色国产综合视频| 欧美一级二级在线观看| 亚洲国产成人在线| 亚洲成av人片在线观看| 国产精品99久久久久| 欧美亚洲国产一区二区三区 | 欧美亚日韩国产aⅴ精品中极品| 国产成人福利片| 欧美日韩国产一级片| 国产日韩欧美高清| 亚洲影院在线观看| 国产精品888| 欧美人体做爰大胆视频| 国产精品久久午夜夜伦鲁鲁| 日韩精品亚洲一区| 暴力调教一区二区三区| 日韩欧美国产高清| 一区二区三区不卡在线观看| 国产综合久久久久久久久久久久| 欧美韩国一区二区| 亚洲男女一区二区三区| 狠狠色丁香久久婷婷综合_中| 91蜜桃网址入口| 日韩一区二区三区三四区视频在线观看 | 国产精品一区二区不卡| 欧美精品久久久久久久久老牛影院| 久久九九国产精品| 秋霞影院一区二区| 欧美无砖专区一中文字| 久久影音资源网| 免费欧美日韩国产三级电影| 欧美无乱码久久久免费午夜一区| 国产欧美日韩在线看| 麻豆国产精品777777在线| 欧美中文字幕亚洲一区二区va在线| 中文字幕免费不卡| 国产乱码精品1区2区3区| 欧美一区二区啪啪| 亚洲一区二区三区四区在线免费观看| 成人自拍视频在线| 精品奇米国产一区二区三区| 午夜精品久久久久久久99樱桃| 色综合天天综合色综合av| 国产精品午夜电影| 国产麻豆精品视频| 亚洲精品一区二区三区影院| 美女视频免费一区| 日韩欧美激情一区| 乱一区二区av| 日韩精品中午字幕| 精品一区二区免费视频| 欧美va亚洲va在线观看蝴蝶网| 欧美aaa在线| 亚洲精品一区二区三区99|