noj算法 堡垒问题 回溯法

描述:

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

输入:

每个测例以一个整数n(1<=n<=4)开始,表示城堡的大小。接下来是n行字符每行n个,‘X’表示该位置是墙,‘.’表示该位置是空格。n等于0标志输入结束。

输出:

每个测例在单独的一行输出一个整数:最多修建堡垒的个数。

输入样例:

4
.X..
....
XX..
....
2
XX
.X
3
.X.
X.X
.X.
3
...
.XX
.XX
4
....
....
....
....
0

输出样例:

5
1
5
2
4

题解:

逐个地点的搜索是否能放堡垒,并利用一个回溯,求出所有结果。

代码:

#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
char a[5][5]={0};
int maxn=0,cur=0;   //maxn记录最终最优解,cur记录每一次最优解

bool iscanput(int x,int y,int n)
{
    int r=x;
    int c=y;
    if(a[x][y]!=‘.‘)
        return false;
    while(y>=0&&a[r][y]==‘.‘)
            {y--;}
    if(y<0||(y>=0&&a[r][y]==‘X‘)){
        while(x>=0&&a[x][c]==‘.‘) x--;
        if(x<0||(x>=0&&a[x][c]==‘X‘)) return true;
    }
    return false;
}

void Search(int i,int n)
{
    int x=i/n;
    int y=i%n;
    if(i==n*n){
        if(maxn<cur)
            maxn=cur;
    }
    else{
        if(iscanput(x,y,n)){   //看(x,y)是否能存放堡垒
            a[x][y]=‘T‘;
            cur++;
            Search(i+1,n);
            cur--;
            a[x][y]=‘.‘;
        }
        Search(i+1,n);
    }
}

int main()
{
    int n,i,j;
    while(cin>>n,n){
        maxn=0;
        cur=0;
        for(i=0;i<n;i++)
            for(j=0;j<n;j++)
            cin>>a[i][j];
        Search(0,n);
        cout<<maxn<<endl;
    }
    return 0;
}                

原文地址:https://www.cnblogs.com/y1040511302/p/9733364.html

时间: 2024-11-01 12:42:55

noj算法 堡垒问题 回溯法的相关文章

noj算法 素数环 回溯法

描述: 把1到20这重新排列,使得排列后的序列A满足:a. 任意相邻两个数之和是素数b. 不存在满足条件a的序列B使得:A和B的前k(0 <= k <= 19)项相同且B的第k+1项比A的第k+1项小.(即按字典序排列的第一项) 输入: 没有输入. 输出: 输出A,两个数字之间用一个空格隔开,第一个数字前面和最后一个数字后面没有空格. 题解: 只打印字典序最小的一项即可.逐个数判断能否与我们放好的前一个数相加为素数,若不是素数,则回溯:若是,继续搜索.找到满足条件的第一个解即可. 代码: #i

noj算法 装载问题 回溯法

描述: 有两艘船,载重量分别是c1. c2,n个集装箱,重量是wi (i=1-n),且所有集装箱的总重量不超过c1+c2.确定是否有可能将所有集装箱全部装入两艘船. 输入: 多个测例,每个测例的输入占两行.第一行一次是c1.c2和n(n<=10):第二行n个整数表示wi (i=1-n).n等于0标志输入结束. 输出: 对于每个测例在单独的一行内输出Yes或No. 输入样例: 7 8 28 77 9 28 80 0 0 输出样例: YesNo 题解: 变形的01背包问题,先按最优解把c1装好,在看

noj算法 迷宫问题 回溯法

描述: 给一个20×20的迷宫.起点坐标和终点坐标,问从起点是否能到达终点. 输入: 多个测例.输入的第一行是一个整数n,表示测例的个数.接下来是n个测例,每个测例占21行,第一行四个整数x1,y1,x2,y2是起止点的位置(坐标从零开始),(x1,y1)是起点,(x2,y2)是终点.下面20行每行20个字符,'.'表示空格:'X'表示墙. 输出: 每个测例的输出占一行,输出Yes或No. 输入样例: 20 0 19 19....................XXXXXXXXXXXXXXXXX

noj算法 踩气球 回溯法

描述: 六一儿童节,小朋友们做踩气球游戏,气球的编号是1-100,两位小朋友各踩了一些气球,要求他们报出自己所踩气球的编号的乘积.现在需要你编一个程序来判断他们的胜负,判断的规则是这样的:如果两人都说了真话,数字大的人赢:如果两人都说了假话,数字大的人赢:如果报小数字的人说的是真话而报大数字的人说谎,则报小数字的人赢(注意:只要所报的小数字是有可能的,即认为此人说了真话). 输入: 输入为两个数字,0 0表示结束: 输出: 输出为获胜的数字. 输入样例: 36 62 49 343 0 0 输出样

五大常用算法之四:回溯法

(转自:http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741376.html) 1.概念 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径. 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”. 许

算法思想之回溯法

一.概念 回溯:当把问题分成若干步骤并递归求解时,如果当期步骤没有合法选择,则函数将返回上一级递归调用,这种现象称为回溯. 回溯算法应用范围:只要把待求解问题分成不太多的步骤,每个步骤又只有不太多的选择,即可以考虑用回溯法. 回溯算法实际上是一个递归枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径. 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不

(转)五大常用算法之四:回溯法

http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741376.html 1.概念 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径. 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”. 许多复杂的,

算法学习笔记——回溯法

一.基本概念 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就"回溯"返回,尝试别的路径. 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为"回溯点". 许多复杂的,规模较大的问题都可以使用回溯法,有"通用解题方法"的美称. 二.基本思想 在包

经典算法学习之回溯法

回溯法的应用范围:只要能把待求解的问题分成不太多的步骤,每个步骤又只有不太多的选择就可以考虑使用回溯法. 若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束. 而若使用回溯法求任一个解时,只要搜索到问题的一个解就可以结束. 回溯法将问题的候选解按照某一顺序逐一枚举和检验.当发现当前候选解不可能是解时,就选择下一个候选解,若当前候选解符合要求,且还未达到求解的规模,则继续扩展当前候 选解的规模,如果候选解已经满足了所有要求,并且也达到了问题的规模,那么该候选解就是