❶ 棋盤覆蓋問題的演算法分析
設T(k)是演算法ChessBoard覆蓋一個2^k×2^k棋盤所需時間,從演算法的劃分
策略可知,T(k)滿足如下遞推式:
T(k) = 1 當k=0時
T(k) = 4T(k-1) 當k>0時
解此遞推式可得T(k)=O(4^k)。
❷ 求8x8棋盤完美覆蓋的演算法
當k>0時,將2k×2k棋盤分割為4個2k-1×2k-1 子棋盤(a)所示。特殊方格必位於4個較小子棋盤之一中,其餘3個子棋盤中無特殊方格。為了將這3個無特殊方格的子棋盤轉化為特殊棋盤,可以用一個L型骨牌覆蓋這3個較小棋盤的會合處,如 (b)所示,從而將原問題轉化為4個較小規模的棋盤覆蓋問題。遞歸地使用這種分割,直至棋盤簡化為棋盤1×1。
❸ 一道棋盤演算法問題!用(c++)
真巧,pku 1753就是這題。。
前幾天ICPC訓練的時候還寫過,現在懶得再寫了,要用到bfs,我幫你找到了這題的解題報告,你看看吧:
解題思路:
BFS 即寬搜
因為這題說要找出最小值,也就是求最優值問題,那麼,很快就可以想到DP 或者
搜索,而這題很難想出階段以及狀態,所以,構造DP的解法是比較困難的,至於
到底可不可以用DP,我也沒有繼續深思過,所以,我就想到直接搜索,把所有走法
都模擬出來,然後,哪種走法最快能夠實現全盤為白或黑,則答案就出來了!
搜索有BFS和DFS兩種,而BFS有能夠求出最優值的特點,故考慮用BFS!
方法:
如果把走第i步之前,盤子上所有棋子構成的狀態記為S(i-1),並且,初始狀態
記為S(0)。而且,可以發現每走一步時,在棋盤上都有4*4=16中選擇!但,當
如果盤子上出現的狀態在之前也出現過,那麼,就可以不用再繼續走了!(即剪枝)
我們從第一步開始。。。
把走完第一步後盤子的所有狀態都保存起來,如果用
很多個二維數組來保存這些狀態就浪費空間了,並且,在之後的要尋找當前狀態是否
已經出現過,也會出現麻煩!想一想,因為棋子是黑白兩面,可以等價為「0」和「1」
兩種性質,那麼如果用一個一維數組保存起來的話,例如:
bwwb
bbwb
bwwb
bwww 1001110110011000
那麼很快又可以發現另一個特點,圖只有2^16個狀態。
然後,開一個數組sign[65535]標記已經訪問過的狀態,則問題就迎刃而解了!
我的程序:
Problem: 1753 User: jlthero
Memory: 504K Time: 32MS
Language: C++ Result: Accepted
Source Code
#include<stdio.h>
#include<string.h>
#include<vector>
#include<iostream>
using namespace std;
char piece[5][5];
int bina[16];
int sign[65536];
int ans;
int toint()
{
int value=0;
int i;
for(i=15;i>=0;i--)
{
value=value*2;
value+=bina[i];
}
return value;
}
void tochar(int n)
{
int i;
for(i=0;i<16;i++)
{
bina[i]=n%2;
n=n/2;
}
}
void slip(int i)
{
bina[i]=1-bina[i];
if(i%4!=0)
bina[i-1]=1-bina[i-1];
if(i%4!=3)
bina[i+1]=1-bina[i+1];
if(i-4>=0)
bina[i-4]=1-bina[i-4];
if(i+4<16)
bina[i+4]=1-bina[i+4];
}
int DFS()
{
vector<int>quene;
int i=0,j;
int value0,value1;
value0=toint();
if(value0==0||value0==65535)
return 0;
else if(sign[value0]==0)
{
quene.push_back(value0);
sign[value0]=1;
}
while(i<quene.size())
{
value0=quene[i];
tochar(value0);
for(j=0;j<16;j++)
{
slip(j);
value1=toint();
if(value1==0||value1==65535)
return sign[value0];
else if(sign[value1]==0)
{
quene.push_back(value1);
sign[value1]=sign[value0]+1;
}
slip(j);
}
i++;
}
return -1;
}
int main()
{
int i,j;
int t,ans;
while(scanf("%s %s %s %s",piece[0],piece[1],piece[2],piece[3])!=EOF)
{
for(i=0;i<4;i++)
{
t=i*4;
for(j=0;j<4;j++)
bina[t+j]=(piece[i][j]=='b'?1:0);
}
memset(sign,0,sizeof(sign));
ans=DFS();
if(ans==-1)
printf("Impossible\n");
else
printf("%d\n",ans);
}
return 0;
}
下面是王熾輝師兄的代碼,代碼長度要比我短很多^_^:
Problem: 1753 User: wangchi
Memory: 148K Time: 30MS
Language: C Result: Accepted
Source Code
#include<stdio.h>
#include<string.h>
#define MAX 1000000
int a[16], b[16], min;
char ch[4][5];
int legal()
{
int i, t, sum;
static int k = -1;
t = (a[0] + b[0] + b[1] + b[4]) % 2;
for(i = 1; i < 16; i++){
sum = a[i] + b[i];
if(i%4 != 0) sum += b[i-1];
if(i%4 != 3) sum += b[i+1];
if(i-4 >= 0) sum += b[i-4];
if(i+4 < 16) sum += b[i+4];
if(sum % 2 != t) return 0 ;
}
return 1;
}
void dfs(int i, int num)
{
if(i==16) {
if(min > num && legal()) min = num;
return;
}
b[i] = 0;
dfs(i+1, num);
b[i] = 1;
dfs(i+1, num+1);
}
int main()
{
int i, j, t;
while(scanf("%s%s%s%s", ch[0], ch[1], ch[2], ch[3]) != EOF){
for(i = 0; i < 4; i++){
t = i * 4;
for(j = 0; j < 4; j++)
a[t+j] = (ch[i][j]=='w')?0:1;
}
min = MAX;
dfs(0, 0);
if(min == MAX) printf("Impossible\n");
else printf("%d\n", min);
}
return 0;
}
❹ 棋盤覆蓋問題的演算法實現
下面討論棋盤覆蓋問題中數據結構的設計。
(1)棋盤:可以用一個二維數組board[size][size]表示一個棋盤,其中,size=2^k。為了在遞歸處理的過程中使用同一個棋盤,將數組board設為全局變數;
(2)子棋盤:整個棋盤用二維數組board[size][size]表示,其中的子棋盤由棋盤左上角的下標tr、tc和棋盤大小s表示;
(3)特殊方格:用board[dr][dc]表示特殊方格,dr和dc是該特殊方格在二維數組board中的下標;
(4) L型骨牌:一個2^k×2^k的棋盤中有一個特殊方格,所以,用到L型骨牌的個數為(4^k-1)/3,將所有L型骨牌從1開始連續編號,用一個全局變數t表示。
設全局變數t已初始化為0,分治法求解棋盤覆蓋問題的演算法用C++語言描述如下:
void ChessBoard(int tr, int tc, int dr, int dc, int size)
{
int s, t1; //t1表示本次覆蓋所用L型骨牌的編號
if (size == 1) return; //棋盤只有一個方格且是特殊方格
t1 = ++t; // L型骨牌編號
s = size/2; // 劃分棋盤
if (dr < tr + s && dc < tc + s) //特殊方格在左上角子棋盤中
ChessBoard(tr, tc, dr, dc, s); //遞歸處理子棋盤
else{ //用 t1號L型骨牌覆蓋右下角,再遞歸處理子棋盤
board[tr + s - 1][tc + s - 1] = t1;
ChessBoard(tr, tc, tr+s-1, tc+s-1, s);
}
if (dr < tr + s && dc >= tc + s) //特殊方格在右上角子棋盤中
ChessBoard(tr, tc+s, dr, dc, s); //遞歸處理子棋盤
else { //用 t1號L型骨牌覆蓋左下角,再遞歸處理子棋盤
board[tr + s - 1][tc + s] = t1;
ChessBoard(tr, tc+s, tr+s-1, tc+s, s);
}
if (dr >= tr + s && dc < tc + s) //特殊方格在左下角子棋盤中
ChessBoard(tr+s, tc, dr, dc, s); //遞歸處理子棋盤
else { //用 t1號L型骨牌覆蓋右上角,再遞歸處理子棋盤
board[tr + s][tc + s - 1] = t1;
ChessBoard(tr+s, tc, tr+s, tc+s-1, s);
}
if (dr >= tr + s && dc >= tc + s) //特殊方格在右下角子棋盤中
ChessBoard(tr+s, tc+s, dr, dc, s); //遞歸處理子棋盤
else { //用 t1號L型骨牌覆蓋左上角,再遞歸處理子棋盤
board[tr + s][tc + s] = t1;
ChessBoard(tr+s, tc+s, tr+s, tc+s, s);
}
}
❺ 馬踏棋盤演算法
#include <stdio.h>
main()
{
int a[9][9],object[9][9],step[9][3]={{0,0,0},{1,1,2},{2,1,-2},{3,-1,2},{4,-1,-2},
{5,2,1},{6,2,-1},{7,-2,1},{8,-2,-1}};
int i,j,k,x,y,z,m,n,min;
for(i=1;i<=8;i++)
for(j=1;j<=8;j++)
a[i][j]=0; /* clear data in array */
for(i=1;i<=8;i++)
for(j=1;j<=8;j++)
for(k=1;k<=8;k++)
{
x=i;y=j;
x=x+step[k][1];
y=y+step[k][2];
if(x>=1&&x<=8&&y>=1&&y<=8)
a[i][j]++ ; /* initilize array */
} /* start col and row;*/
printf("Please inpute start position x,y\n");
scanf("%d,%d",&m,&n);
for(z=1;z<=64;z++)
{
min =10;
object[m][n]=z;
a[m][n]=0;
for(k=1;k<=8;k++)
{
x=m+step[k][1];
y=n+step[k][2];
if(x>=1&&x<=8&&y>=1&&y<=8)
if(a[x][y]!=0)
{
--a[x][y];
if(a[x][y]<min)
{
min=a[x][y];
i=x;
j=y;
}
}
}
m=i;n=j;
}
for(i=1;i<=8;i++)
{
for(j=1;j<=8;j++)
printf("%6d",object[i][j]);
printf("\n");
}
}
請採納答案,支持我一下。
❻ 機器人走棋盤演算法採用的什麼控制結構
循環結構
_饈且桓黽虻サ納嬗蝸罰憧刂埔桓齷魅舜右桓銎迮痰鈉鶚嫉?(1,1)走到棋盤的終點(n,m)。游戲的規則描述如下:
? 1.機器人一開始在棋盤的起始點並有起始點所標有的能量。
? 2.機器人只能向右或者向下走,並且每走一步消耗一單位能量。
? 3.機器人不能在原地停留。
? 4.當機器人選擇了一條可行路徑後,當他走到這條路徑的終點時,他將只有終點所標記的能量。
❼ 現在所有的圍棋演算法,盡量全一點
有兩種新型的樹演算法,我在圍棋天地上看到過,歐洲人發現的,因為這兩種演算法,電腦棋力提升了一大截,你可以找找。
❽ 中國象棋中怎麼算做磨棋
你覺得磨的,都是磨棋
❾ 棋盤覆蓋演算法
import java.util.*;
public class TestChessBoard {
public static void main(String[] args) {
int tr=0,tc=0,dr=1,dc=2,size=8;
ChessBoard.chessBoard(tr,tc,dr,dc,size);
ChessBoard.display();
}
}
class ChessBoard {
public static int tile = 0;
public static int[][] board= new int[10][10];
public static void chessBoard (int tr,int tc,int dr,int dc,int size) {
if(size == 1) return;
int t = tile++ , s = size/2;
if(dr<tr+s && dc<tc+s){
chessBoard(tr,tc,dr,dc,s);
}else {
board[tr+s-1][tc+s-1] = t;
chessBoard(tr,tc,tr+s-1,tc+s-1,s);
}
if(dr<tr+s && dc>=tc+s){
chessBoard(tr,tc+s,dr,dc,s);
}else {
board[tr+s-1][tc+s] = t;
chessBoard(tr,tc+s,tr+s-1,tc+s,s);
}
if(dr>=tr+s && dc<tc+s) {
chessBoard(tr+s,tc,dr,dc,s);
}else {
board[tr+s][tc+s-1] = t;
chessBoard(tr+s,tc,tr+s,tc+s-1,s);
}
if(dr>=tr+s && dc>=tc+s) {
chessBoard(tr+s,tc+s,dr,dc,s);
}else {
board[tr+s][tc+s] = t;
chessBoard(tr+s,tc+s,tr+s,tc+s,s);
}
}
public static void display() {
for(int i=0;i<8;i++){
for(int j=0;j<8;j++) {
System.out.print(" "+board[i][j]);
}
System.out.println();
}
}
}
❿ 棋盤人工智慧演算法
即可吃掉對方的子?
不應該是這樣的吧!我想應該是 滿足條件即可收回自己的子,然後到一方沒有子可放置為止!
you are so mean! 太沒有誠意了吧 哈哈~~~
高手在哪裡????高手在哪裡????高手在哪裡????高手在哪裡????高手在哪裡????高手在哪裡????高手在哪裡????高手在哪裡????高手在哪裡????高手在哪裡????高手在哪裡????高手在哪裡????高手在哪裡????高手在哪裡????高手在哪裡????高手在哪裡???? ....