算法练习——堡垒问题

来源:互联网 发布:手机淘宝店标尺寸 编辑:程序博客网 时间:2024/05/11 04:30

如图城堡是一个4×4的方格,为了保卫城堡,现需要在某些格子里修建一
些堡垒。城堡中的某些格子是墙,其余格子都是空格,堡垒只能建在空格里,每个堡垒都可以向上下左右四个方向射击,如果两个堡垒在同一行或同一列,且中间没有墙相隔,则两个堡垒都会把对方打掉。问对于给定的一种状态,最多能够修建几个堡垒。这里写图片描述

#include "stdio.h"#include <Windows.h>void readdata();void search(int);void printresult();void checkmax();int canplace(int);void place(int);void takeout(int);int A[4][4];int n=4;int max=0;int main(){    readdata();           //读入数据    search(0);            //递归搜索    printresult();    system("pause");}void readdata(){    for(int i=0;i<n;i++)        for(int j=0;j<n;j++)        {            scanf("%d",&A[i][j]);        }}void search(int m){    int row, col;    row=m/n;              //求第m个格子的行号    col=m%n;              //求第m个格子的列号    if(m>=n*n)        checkmax();       //检查当前解是否是可行解,若是则把它的价值与max比较    else    {        search(m+1);      //该位置不放堡垒递归搜索下一个位置        if(canplace(m))    //判断第m个格子是否能放堡垒        {            place(m);     //在第m个格子上放置一个堡垒            search(m+1);  //递归搜索下一个位置            takeout(m);   //去掉第m个格子上放置的堡垒        }    }}/************************************************************************/  /* 判断是否可以放城堡,m每次递增1,假设判断arr[row][col]位置是否可以放,分析知row的下面必然没有城堡,col的右边必然没有城堡  故只需要判断row的上边和col的左边是有堡垒即可,若能够理解只要第一三判断即可以下两种方法均可做判断  */  /************************************************************************/  int canplace(int m)//判断是否能将A[m/n][m%n]置为堡垒{    int row,col,r,c;    row=m/n; col=m%n;//行//列    r=row;   c=col;  //保存行列值    if(A[row][col]==1||A[row][col]==2)        return 0; //是城墙,是堡垒,不能置为堡垒    else    {        for(r=row;r>0;r--)        {            if(r-1>=0&&A[r-1][col]==1)                break;            if(r-1>=0&&A[r-1][col]==2)            {                return 0;                break;            }        }        for(r=row;r<n;r++)        {            if(r+1<=n&&A[r+1][col]==1)                break;            if(A[r+1][col]==2)            {                return 0;                break;            }        }        for(c=col;c>0;c--)        {            if(c-1>=0&&A[row][c-1]==1)                break;            if(c-1>=0&&A[row][c-1]==2)            {                return 0;                break;            }        }        for(c=col;c<n;c++)        {            if(c+1<=n&&A[row][c+1]==1)                break;            if(c+1<=n&&A[row][c+1]==2)            {                return 0;                break;            }        }        return 1;        /**        for(r=row;r>0;r--)        if(r-1>=0&&(A[r-1][col]==1||A[r-1][col]==2))        if(A[r-1][col]==2)return 0;        else break;        for(r=row;r<n;r++)        if(r+1<=n&&(A[r+1][col]==1||A[r+1][col]==2))        if(A[r+1][col]==2)return 0;        else break;        for(c=col;c>0;c--)        if(c-1>=0&&(A[row][c-1]==1||A[row][c-1]==2))        if(A[row][c-1]==2)return 0;        else break;        for(c=col;c<n;c++)        if(c+1<=n&&(A[row][c+1]==1||A[row][c+1]==2))        if(A[row][c+1]==2)return 0;        else break;        return 1;**/    }}void place(int m){    int row;    int col;    row=m/n;    col=m%n;    A[row][col]=2;}void takeout(int m){    int row;    int col;    row=m/n;    col=m%n;    A[row][col]=0;}void checkmax(){    int sum=0;    for(int i=0;i<n;i++)        for(int j=0;j<n;j++)            if(A[i][j]==2)                sum++;    if(sum>max)//取置堡垒个数最多的        max=sum;}void printresult(){    printf("%d\n",max);}

程序运行结果如下:
这里写图片描述

0 0