藍橋杯 標題:縱橫火柴旗子

【編程題】
    這是一個縱橫火柴棒遊戲。如圖[1.jpg],在一個3x4的方格中,遊戲的雙方輪流放置火柴棒。其規則是:
    1. 不能放置在已經放置火柴棒的地方(即只能在空格中放置)。
    2. 火柴棒的方向只能是垂直或水平放置。
    3. 火柴棒不能與其它格子中的火柴“連通”。所謂連通是指兩根火柴棒可以連成一條直線,且中間沒有其它不同方向的火柴“阻攔”。
    例如:圖[1.jpg]所示的局面下,可以在C2位置豎直放置,但不能水平放置,因爲會與A2連通。同樣道理,B2,B3,D2此時兩種方向都不可以放置。但如果C2豎直放置後,D2就可以水平放置了,因爲不再會與A2連通(受到了C2的阻擋)。
    4. 遊戲雙方輪流放置火柴,不可以棄權,也不可以放多根。直到某一方無法繼續放置,則該方爲負(輸的一方)。

    遊戲開始時可能已經放置了多根火柴。

    你的任務是:編寫程序,讀入初始狀態,計算出對自己最有利的放置方法並輸出。


    如圖的局面表示爲:
    00-1
    -000
    0100
    即用“0”表示空格位置,用“1”表示豎直放置,用“-”表示水平放置。
【輸入、輸出格式要求】
    用戶先輸入整數 n(n<100), 表示接下來輸入 n 種初始局面,每種局面佔3行(多個局面間沒有空行)。
    程序則輸出對應的每種初始局面,計算出的最佳走法(行號+列號+放置方式)。
    例如:用戶輸入:
    2
    0111
    -000
    -000
    1111
     ----
    0010
   則程序可以輸出:
    00-
    211
   輸出結果的含義爲:
   對第一個局面,在第0行第0列水平放置
   對第二個局面,在第2行第1列垂直放置
   注意:
   行號、列號都是從0開始計數的。
   對每種局面可能有多個最佳放置方法(解不唯一),只輸出一種即可。

   例如,對第一個局面,001 也是正解;最第二個局面,201也是正解。

#include<iostream>
using namespace std;
char grid[3][4];
char type[]={'1','-'};
bool isPositon(int x,int y,char c)//判斷該位置是否可以放 
{
		if(c=='1')//1有兩種情況不能放,上下都不能爲1,但可以用-隔開 
		{
			for(int i=x-1;i>=0;i--)
			{
				if(grid[i][y]==c)
					return false;
				else
				break;
			}
			for(int i=x+1;i<3;i++)
			{
				if(grid[i][y]==c)
					return false;
				else
				break;
			}
		}
		else //-也有兩種情況,左右不能爲-,但可以用1隔開 
		{
			for(int j=y-1;j>=0;j--)
			{
				if(grid[x][j]=='-')
					return false;
				else break;
			}
			for(int j=y+1;j<4;j++)
			{
				if(grid[x][j]=='-')
					return false;
				else break;
			}
		}
		return true;
}
bool isWin(int x,int y,char c)//判斷在(x,y)放c能不能贏 
{
	if(!isPositon(x,y,c))//不能放 
		return false;
	else 
	{
		//枚舉當前情況下,對方有沒有贏的可能 
		for(int i=0;i<3;i++) 
		{
			for(int j=0;j<4;j++)
			{
				if(grid[i][j]=='0')
				{
					for(int k=0;k<2;k++)
					{
						grid[i][j]=type[k];
						if(isWin(i,j,type[k]))//對方能贏 
						{
							grid[i][j]='0'; 
							return false;//我們就不能贏 
						}
						grid[i][j]='0';	
					}
				}	
			}	
		}
		return true;//能贏	
	}
}
void Judge()
{
	//枚舉可以放的情況 
	for(int i=0;i<3;i++)
		{
			for(int j=0;j<4;j++)
			{
				if(grid[i][j]=='0')
				{
					for(int k=0;k<2;k++)
					{
						grid[i][j]=type[k];
						if(isWin(i,j,type[k]))//放該位置能贏 
						{
							cout<<i<<' '<<j<<' '<<type[k]<<endl;
							return ;
						}
						grid[i][j]='0';
					}
				}
			}	
		}
} 
int main()
{
	int n;
	cin>>n;
	while(n--)
	{
		//輸入數據 
		for(int i=0;i<3;i++)
		{
			for(int j=0;j<4;j++)
			{
				cin>>grid[i][j];	
			}	
		}
		//枚舉 
		Judge(); 
	} 
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章