當前位置:首頁 » 編程語言 » 農夫過河c語言演算法位運算
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

農夫過河c語言演算法位運算

發布時間: 2023-02-21 09:30:07

c語言,農夫過河問題

程序就是求解農夫過河問題:
農夫帶著一狼,一羊和一些菜過河。河邊只有一船,一次農夫只能帶一樣東西。無人時,狼要吃羊,羊要吃菜,程序將找出所有農夫過河的方案。

首先要表示狼,羊,菜和農夫所在的位置,4者的位置有本岸和對岸兩種情況,分別用0和1表示,4者,所以用一個有4元素的數組。為了要記錄每一步,程序中使用了一個二維數組a[MAX_STEP][4],記錄每一步4者所在位置。第一步就是a[0],第二布是a[1]...而,a[0][0]就表示第一步狼在本岸(0)還是對岸(1),a[0][1]表示第一步羊在本岸還是對岸......
為了記錄每一次農夫過河時的狀態,使用了一個數組b[MAX_STEP],數組中的元素的值可能為-1, 0, 1, 2,分別表示農夫在過河時,是空手,帶狼,帶羊,帶菜。

第一步的狀態是狼,羊,菜和農夫都在本案,所以a[0][0]到a[0][3]都是0,本來應該初始化一下,但a是全局變數,所以自動初始化為0,所以程序中省下了這一步。
search是一個遞歸函數,通過不斷的查找可能的下一步,找出一個方案,是一種深度優先搜索。
a[iStep][0] + a[iStep][1] + a[iStep][2] + a[iStep][3] == 4意味著第 iStep時,a[iStep][0]到a[iStep][3]都為1,表示4者都到了對岸。所以輸出結果。
for (i = 0; i < iStep; i++)
{
if (a[i][3] == 0)
{
printf("%s到對岸\n", name[b[i] + 1]);
}
else
{
printf("%s回本岸\n", name[b[i] + 1]);
}
}
輸出每一步
a[i][3]是農夫在本岸還是對岸,如果為0,在本岸,下一步肯定是到對岸,所以列印"...到對岸",而name[b[i]+1]找出對應帶的東西的描述。
for (i = 0; i < iStep; i++)
{
if (memcmp(a[i], a[iStep], sizeof(a[i])) == 0)
{
return;
}
}
判定是否會死循環,如果當前狀態在以前出現過,那麼就會出現死循環。用當前這步的狀態a[iStep]和以前的所有步a[i] (i=0; i <iStep; i++)比較。memcmp是內存比較函數,可以用於比較數組,返回值為0,表示數組中所有值相同。
如果相同,就直接返回,不再查找。

if (a[iStep][1] != a[iStep][3] && (a[iStep][2] == a[iStep][1] || a[iStep][0] == a[iStep][1]))
{
return;
}

判定羊會吃菜,或狼會吃羊的情況。
當農夫和羊在一起的時候,狼不會吃羊,羊也不會吃菜,所以只有當農夫和羊不在一起(a[iStep][1] != a[iStep][3])時,才可能發生「吃」的狀態。
而且「吃」的情況必須是在菜和羊在一起(a[iStep][2] == a[iStep][1])或者羊和狼在一起(a[iStep][0] == a[iStep][1])
發生吃的情況是,返回,不再查找。

for (i = -1; i <= 2; i++)
{
b[iStep] = i;
memcpy(a[iStep + 1], a[iStep], sizeof(a[iStep + 1]));
a[iStep + 1][3] = 1 - a[iStep + 1][3];
if (i == -1)
{
search(iStep + 1);
}
else if (a[iStep][i] == a[iStep][3])
{
a[iStep + 1][i] = a[iStep + 1][3];
search(iStep + 1);
}
}
但現在,已經確保了上一步是「安全」的,可以繼續查找。
-1, 0, 1, 2分別表示渡河時4種情況,空手,帶狼,帶羊,帶菜。
memcpy(a[iStep + 1], a[iStep], sizeof(a[iStep + 1])); 復制當前步的數組到下一步。
農夫的狀態肯定會發生改變,所以a[iStep + 1][3] = 1 - a[iStep + 1][3]; 因為當a為0或1時,a = 1 - a會使a在0和1之間切換。
如果i== -1,表示空手,狼,羊,菜的狀態都不會發生改變,所以直接搜索下一步(search(iStep + 1); )
否則要被帶過去的東西(0, 1, 2分別表示0, 1, 2)的狀態需要改變。
要帶的東西必須和農夫同在本案或對岸(a[iStep][i] == a[iStep][3]),才可能帶得了。只有在這種情況下,使要帶的東西的狀態和農夫相同(a[iStep + 1][i] = a[iStep + 1][3];),並開始下一步的搜索(search(iStep + 1))。

❷ 僅用c語言能編出哪些小游戲

可以編寫狼追兔子游戲,擲骰子游戲,24點游戲,井字棋游戲,農夫過河游戲,掃雷小游戲,人機猜數游戲,三色球游戲, 推箱子游戲,坦克大戰游戲,貪吃蛇游戲等。

❸ 哪位會c語言的老哥幫我看看 位運算農夫過河問題

scanf("%c",&p[i]); fflush(stdin); //加一句清輸入緩沖區即可。
另外,int *move(int *M,int i){}
改為 int move(int *M,int i){} 否則 a=move(&a,3); 這種句子變數類型不匹配。

❹ 農夫過河問題的求解

#include<iostream.h>
#include<stdio.h>
#defineMAXNUM 20
typedefstruct //順序隊列類型定義
{
int f, r; //f表示頭,r 表示尾
int q[MAXNUM];//順序隊
}SeqQueue,*PSeqQueue;

PSeqQueuecreateEmptyQueue_seq( ) //創建隊列
{
PSeqQueue paqu = new SeqQueue;
if(paqu == NULL)
cout<<"Out of space!"<<endl;
else
paqu->f=paqu->r=0;
return (paqu);
}
intisEmptyQueue_seq( PSeqQueue paqu ) //判斷paqu 所指是否是空隊列
{
return paqu->f==paqu->r;
}
voidenQueue_seq(PSeqQueue paqu,int x) //在隊列中插入一元素 x
{
if ((paqu->r+1)%MAXNUM==paqu->f)
cout<<"隊列已滿."<<endl;
else
{
paqu->q[paqu->r]=x;
paqu->r=(paqu->r+1)%MAXNUM;
}
}
void deQueue_seq(PSeqQueue paqu) //刪除隊列頭部元素
{
if( paqu->f==paqu->r)
cout<<"隊列為空"<<endl;
else
paqu->f=(paqu->f+1)%MAXNUM;
}
intfrontQueue_seq( PSeqQueue paqu ) //對非空隊列,求隊列頭部元素
{
return (paqu->q[paqu->f]);
}
intfarmer(int location) //判斷農夫位置對0做與運算,還是原來的數字,用來判斷位置
{
return 0 != (location & 0x08);
}
intwolf(int location) //判斷狼位置
{
return 0 != (location & 0x04);
}
intcabbage(int location) //判斷白菜位置
{
return 0 != (location & 0x02);
}
intgoat(int location) //判斷羊的位置
{
return 0 !=(location & 0x01);
}
intsafe(int location) // 若狀態安全則返回 true
{
if ((goat(location) == cabbage(location))&& (goat(location) != farmer(location)) )
return 0;
if ((goat(location) == wolf(location))&& (goat(location) != farmer(location)))
return 0;
return 1; //其他狀態是安全的

}
void farmerProblem( )
{
int movers, i, location, newlocation;
int route[16]; //記錄已考慮的狀態路徑
int print[MAXNUM];
PSeqQueue moveTo;
moveTo = createEmptyQueue_seq( );//新的隊列判斷路徑
enQueue_seq(moveTo, 0x00); //初始狀態為0
for (i = 0; i < 16; i++)
route[i] = -1; //-1表示沒有記錄過路徑
route[0]=0;
while(!isEmptyQueue_seq(moveTo)&&(route[15] == -1))//隊列不為空,路徑未滿時循環
{
location = frontQueue_seq(moveTo); //從隊頭出隊
deQueue_seq(moveTo);
for (movers = 1; movers <= 8;movers<<= 1)
{
if ((0 != (location & 0x08)) == (0 !=(location & movers)))
{
newlocation = location^(0x08|movers);//或運算
if (safe(newlocation) &&(route[newlocation] == -1))//判斷是否安全,以及路徑是否可用

{
route[newlocation] = location;
enQueue_seq(moveTo, newlocation);

}

}

}

}
/*列印出路徑 */
if(route[15] != -1)
{
cout<<"過河步驟是 : "<<endl;
i=0;
for(location = 15; location >= 0; location= route[location])
{
print[i]=location;
i++;
if (location == 0)
break;
}
int num=i-1;
int temp[20][4];
int j;
for(i=num;i>=0;i--)
{
for(j=3;j>=0;j--)
{
temp[num-i][j]=print[i]%2;
print[i]/=2;
temp[0][j]=0;
temp[num+1][j]=1;
}
}
for(i=1;i<=num;i++)
{
cout<<"\t\t\tNO ."<<i<<"\t";
if(i%2==1)
{
if(temp[i][3]!=temp[i-1][3])
cout<<"農夫帶羊過南岸";
if(temp[i][2]!=temp[i-1][2])
cout<<"農夫帶白菜過南岸";
if(temp[i][1]!=temp[i-1][1])
cout<<"農夫帶狼過南岸";
if(temp[i][3]==temp[i-1][3]&&temp[i][2]==temp[i-1][2]&&temp[i][1]==temp[i-1][1])
cout<<"農夫自己過南岸";
}
else if(i%2==0)
{
if(temp[i][3]!=temp[i-1][3])
cout<<"農夫帶羊回北岸";
if(temp[i][2]!=temp[i-1][2])
cout<<"農夫帶白菜回北岸";
if(temp[i][1]!=temp[i-1][1])
cout<<"農夫帶狼回北岸";
if(temp[i][3]==temp[i-1][3]&&temp[i][2]==temp[i-1][2]&&temp[i][1]==temp[i-1][1])
cout<<"農夫自己回北岸";
}
cout<<endl;
}
}

else
cout<<"Nosolution."<<endl;
}
int main() /*主函數*/
{
farmerProblem();

return 0;
}