欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2088|回復: 1
打印 上一主題 下一主題
收起左側

螞蟻爬桿求解程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:107189 發表于 2016-3-5 20:04 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
//看了前面的鬼魂方法,不用編程甚至不用計算就得出結果
//但我是一個編程初學者,一切只是為了練習,   我花一點時間用C++做一下吧

#include <iostream>
using   namespace   std;

//常量設置
const   int   APOS=0;     //A點位置
const   int   BPOS=27;   //B點位置
const   int   MAXANT=5;//最大螞蟻數
const   int   SPEED=1;   //速度

//全局變量
//初始位置已知量(必須是奇數)
int   poslist[MAXANT]={3,7,11,17,23};

//用五位2進制表示5只螞蟻的開始方向   00000-11111   ,共32種
enum   ANTFLAG{
ANTFLAG1   =     0x1,
ANTFLAG2   =     0x2,
ANTFLAG3   =     0x4,
ANTFLAG4   =     0x8,
ANTFLAG5   =     0x10
    //ANTFLAG6   =     0X20   //假如有更多只
    //...
};
int   antflist[]={ANTFLAG1,ANTFLAG2,ANTFLAG3,ANTFLAG4,ANTFLAG5};

//根據2進制數求螞蟻的起開始方向
int   StartDir(int   val1,int   val2){
int   ir=(antflist[val1]&val2)   ?   1:-1;
return   ir;
}   

class   Ant;

//螞蟻類
class   Ant{
private:
int     m_id;                     //螞蟻id編號(0-4)
bool   m_life;               //生命狀態,初始:1離開桿后:0
int     m_pos;                 //木桿上坐標(0-27)
int     m_dir;                 //方向(1,-1)
int     m_speed;             //速度(1)
int     m_time;               //爬行時間(0-   ?)
public:
static   int   count;//現有蟻數
static   int   antlist[MAXANT];//存儲每個螞蟻的位置
public:
Ant();
void   Init();//螞蟻初始化
int     GetId(){return   m_id;}//獲得ID編號
int     GetTime(){return   m_time;}//返回時間
void   SetDir(int   val){   m_dir=StartDir(m_id,val);}//初始方向
void   CheckLife();   //檢測生命狀態
void   ChangeDir();   //相遇改變方向
void   RunPos();       //每秒后的位置
void   Print(){cout < < "id:   " < <m_id < < "   pos:   " < <m_pos
< < "   dir:   " < <   m_dir < < "   time: "   < <m_time < <endl;}
};//end   ANT

Ant::Ant(){   m_id=count;Init();count++;}

void   Ant::Init(){
        m_pos=poslist[m_id];
m_speed=SPEED;
m_life=1;
m_time=0;
}

void   Ant::CheckLife   (){
if(m_life){
if(m_pos <APOS   ||   m_pos> BPOS)
{
m_life=0;
count--;
}
else
m_time++;         
}
}

void   Ant::ChangeDir(){if(m_life){m_dir*=-1;}}

void   Ant::RunPos(){
if(m_life)
      m_pos+=m_dir*m_speed;
      antlist[m_id]=m_pos;
}

//一個作用螞蟻類的類
class   FunAnt{
public:
int   lasttime;               //最后一只螞蟻離開的時間
Ant   ants[MAXANT];       //螞蟻對象數組共5只
public:
FunAnt(){}

        //設置螞蟻初始方向
void   Funsetdir(int   d){
    for(int   i=0;   i <MAXANT;i++)
    ants[i].SetDir(d);
}
//屏幕輸出所有螞蟻信息
void   print(){
for(int   i=0;i <MAXANT;i++)
ants[i].Print();
}

//一直到最后一只螞蟻離開木桿,輸出每只螞蟻所用時間
void   Run()
{      
while(ants[0].count){
      for(int   i=0;i <MAXANT;i++)
      {   
      ants[i].RunPos();       //移動螞蟻位置
                              ants[i].CheckLife();//檢測螞蟻是否在桿上
      }
      ChangeDir();//檢測,如果螞蟻相遇改變方向,
}
lasttime=ants[0].GetTime();
                for(int   i=1;   i <MAXANT;i++)
{     
bool   b=lasttime <ants[i].GetTime();
if(b){lasttime=ants[i].GetTime();}
}
print();
}

//檢測相鄰螞蟻位置函數,如果位置相同就調用改變方向函數
void   ChangeDir(){
for(int   i=0;i <MAXANT-1;i++)
{
if(ants[0].antlist[i]==ants[0].antlist[i+1])
{
ants[i].ChangeDir();
ants[i+1].ChangeDir();
}
}
}
};

int   Ant::antlist[]={3,7,11,17,23};
int   Ant::count=0;

//////////////////////////////////////////
void   main(){
int     maxlist[32];   //存儲32次的結果數組
for(int   i=0;i <32;i++){
Ant::count   =0;      
FunAnt   a1;     
        a1.Funsetdir(i);
a1.Run();
maxlist[i]=a1.lasttime;
cout < < "lasttime: " < <a1.lasttime < <endl;
}
int   min,max;
min=max=maxlist[0];
for(int   i=0;i <32   ;i++)
{
  if(max <maxlist[i])
max=maxlist[i];
  if(min> maxlist[i])
  min=maxlist[i];
}
cout < < "max: " < <max < <endl
< < "min: " < <min < <endl;
  }//end   main  
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:107189 發表于 2016-3-5 20:04 | 只看該作者
“螞蟻爬桿求解程序”中最關鍵的行為就是如何執行爬桿游戲。法應當如何實現。
玩游戲本身是一個過程,包括從開始、進行中、到最后游戲結束。我們運用分析法進一步細化分解這個過程,這樣得到若干個步驟:
1、 設定好各只螞蟻的初始狀態(位置、頭的朝向等);
2、 開始游戲,讓所有還在木桿上的螞蟻按既定速度連續爬行;
3、 如果某只螞蟻爬出了木桿范圍,則從游戲中將其排除;
4、 如果有螞蟻碰頭了,則讓碰頭的螞蟻同時調頭;
5、 一直循環重復上述步驟,直到所有螞蟻都爬出木桿范圍。

上述步驟,除了第2步外,都很容易用程序代碼來實現。因為程序的執行是一種離散的方式,要精確地模擬螞蟻連續爬行是不可能的;我們需要將螞蟻的爬行動作離散化;而程
序設計中的通行做法就是分割時間片斷,讓螞蟻每次都爬行一小段時間;當這個時間間隔足夠小時,就能近似地模擬實際的爬行過程。于是我們將第2步改造為螞蟻爬行incTime
長的時間,而到了第5步,在繼續循環前要在游戲的總執行時間上增加incTime長的增量。


螞蟻爬桿問題中通過分析法設計的CreepingGame類行為

CreepingGame類的java源碼如下:

/*
  *   CreepingGame螞蟻爬行游戲,定義了相關的規則和玩法
  */
public   class   CreepingGame   {

private   Stick   stick;
private   List <Ant>   antsOnStick;
private   List <Ant>   antsOutofStick;
private   int   currentTime;
private   boolean   gameOver;

public   CreepingGame()   {
antsOnStick   =   new   ArrayList <Ant> ();
antsOutofStick   =   new   ArrayList <Ant> ();
currentTime   =   0;
gameOver   =   false;
}

public   void   setStick(Stick   stick)   {
this.stick   =   stick;
}

public   void   addAntOnStick(Ant   ant)   throws   CreepingException   {
if   (stick   ==   null)
throw   new   CreepingException( "Stick   not   set   yet! ");
else   if   (stick.isOutofRange(ant.getPosition()))
throw   new   CreepingException( "The   ant   is   out   of   stick! ");
antsOnStick.add(ant);
}

/**
  *   依照游戲規則,檢測是否有螞蟻碰頭了,一旦碰頭則兩者要同時調頭
  */
private   void   applyCollisionRule(List <Ant>   ants)   {
List <Ant>   antsTobeCheck   =   new   ArrayList <Ant> ();

antsTobeCheck.addAll(ants);
while   (!antsTobeCheck.isEmpty()){
Ant   antTobeCheck   =   antsTobeCheck.get(0);
antsTobeCheck.remove(antTobeCheck);
Ant   antAtSamePosition   =   null;
for   (Ant   ant   :   antsTobeCheck){
if   (ant.isAtCollisionWith(antTobeCheck)){
antAtSamePosition   =   ant;
break;
}
}
if   (antAtSamePosition   !=   null){
antTobeCheck.changeCreepDirection();
antAtSamePosition.changeCreepDirection();
antsTobeCheck.remove(antAtSamePosition);
}
}
}

/**
  *   以合適的時間間隔來推動游戲的進行
  */
public   void   drivingGame(int   incTime)   {
currentTime   +=   incTime;

for   (Ant   ant   :   antsOnStick){
ant.creeping(incTime);
if   (stick.isOutofRange(ant.getPosition()))
antsOutofStick.add(ant);
}

for   (Ant   ant   :   antsOutofStick){
if   (antsOnStick.contains(ant))
antsOnStick.remove(ant);
}

//“所有螞蟻都爬出木桿范圍”是游戲結束的標準
if   (antsOnStick.isEmpty())
gameOver   =   true;
else{
applyCollisionRule(antsOnStick);
};
}

/**
  *   從頭至尾玩一次游戲
  */
public   void   playGame(int   incTime){
currentTime   =   0;
gameOver   =   false;
while   (!gameOver){
drivingGame(incTime);
}
}

public   int   getPlayTime()   {
return   currentTime   -   0;
}

}

本案例中,遇到的數值都正好是整數,所以只要將每次循環的incTime設為1就可以計算出精確的結果值。但是如果這些數值是帶小數的實數,那么為了盡量求得準確的答案,
incTime要設置成類似0.00001的較小數。這樣將嚴重拖累程序的執行效率(循環次數過多)。
為了提高程序的執行效率,先要定位程序性能的瓶頸;我們發現playGame()方法中的while循環才是瓶頸之所在,于是要繼續針對這個循環來做深入分析。while循環次數過多,
是因為incTime的值過小;而之所以給incTime設置較小數,是為了給程序一個機會來判斷是否出現了螞蟻碰頭、或爬出木桿的事件(螞蟻碰頭將精確地發生在某個時間點,
incTime值過大會使得程序計算可能錯過這個點)。這樣,我們重新將前面以固定間隔incTime來循環執行drivingGame(incTime)的問題,轉化成每次循環前如何計算一個時間值
incTime(不固定),用它來執行drivingGame(incTime),使得推進游戲前進過程中,不會錯過出現螞蟻碰頭、或爬出木桿事件的時間點。最后我們改造while循環,變成先計算
出現下一個螞蟻碰頭或爬出木桿事件所要經歷的最短時間incTime,再以此時間值來推動游戲前進一個時段drivingGame(incTime)。
改造后的CreepingGame類playGame()方法的示例源碼如下:

public   void   playGame(){
currentTime   =   0;
gameOver   =   false;

while   (!gameOver){
/**
*   計算出現下一個螞蟻碰頭或爬出木桿的事件所要經歷的最短時間incTime
*/
int   incTime   =   calcTimeForNextOccurrence();

drivingGame(incTime);
}
}

有興趣的讀者不妨嘗試一下編寫calcTimeForNextOccurrence()的實現代碼。
通過運用分析法,我們實現了“螞蟻爬桿求解程序”中最關鍵的行為——CreepingGame類的playGame()方法。接下來,我們要考慮如何利用游戲室PlayRoom類來求得游戲執行
playGame的最小、最大時間。期間,我們將運用到綜合思維法。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表