概率算法
概率算法允许算法在执行过程中随机地选择下一个计算步骤。在很多情况下,算法在执行过程中面临选择时,随机性选择比最优选择省时,因此概率算法可以在很大程度上降低算法的复杂度。
题目
在 n×n格的棋盘上放置彼此不受攻击的车。按照国际象棋的规则,车可以攻击与之处在同一行或同一列上的棋子。在棋盘上的若干个格中设置了堡垒,战车无法穿越堡垒攻击别的战车。对于给定的设置了堡垒的 n×n格棋盘,设计一个概率算法,在棋盘上放置尽可能多彼此不受攻击的车。
【输入描述】 第1行有1个正整数n。接下来n行中,每行有1个由字符"."和“X”组成的长度为n的字符串,其中X代表堡垒,“.”代表可以放战车的位置。
【输出描述】输出棋盘上可以放置的彼此不受攻击的战车数目。
输入样例
4
. . . .
. . X .
. X . .
. . . .
输出样例
6
C++中int a[10]和int a=new int[10]有什么区别?
1 在使用上int* a=new int[10]需要判断内存是否分配成功,以及在不用时需要使用delete[] a进行内存释放。
2、如果不是a[10],而是a[1000000000]或者更大的话,那一般情况下,就只能使用int* a=new这种方式了。这个涉及到内存存放位置的问题,int a[]这种方式,内存是存放在栈上;int* a=new这种方式,内存是存放在堆上,栈的实际内存是连续内存,因此可分配空间较小,堆可以是非连续内存,因此可以分配较大内存。因此,如果需要分配较大内存,需要分配在堆上;
3、使用int a[10]这种方式,内存大小需要用常量指定,比如这里的10。不能用int m=10;int a[m]这种方式。但是int* a= new这种方式可以,因此在动态分配内存上,后者有非常大的优势。
算法描述
(1) 采用拉斯维加斯概率算法,循环遍历,以概率形式生成一个随机位置。
1 初始化map及vis数组
2 for循环内随机找到一个位置
3 判断该位置是否可放置战车,如果可以就将res增1
4 重置vis数组,进行下一次迭代,更新res.
代码
#include <cstdio>
#include <algorithm>
#include <iostream>
#include<cstring>
using namespace std;
char map[100][100]; int vis[100][100]={0};
int randa(int a,int b){ //产生一个[a,b]的随机数
return rand()%(b-a+1)+a;
}
bool isConflict(int i,int j,int n,int dir){ /*0 up,1 right,2 down,3 left */
switch (dir)
{
case 0:
while(--i>=0){
if(vis[i][j]==1){
return true;
}else{
if(map[i][j]=='X')
break;
}
}
break;
case 1:
while(++j<n){
if(vis[i][j]==1){
return true;
}else{
if(map[i][j]=='X')
break;
}
}
break;
case 2:
while(++i<n){
if(vis[i][j]==1){
return true;
}else{
if(map[i][j]=='X')
break;
}
}
break;
case 3:
while(--j>=0){
if(vis[i][j]==1){
return true;
}else{
if(map[i][j]=='X')
break;
}
}
break;
}
return false;
}
bool place(int i,int j,int n) //判断位置(i,j)是否可以放置
{
if(map[i][j]=='X')
return false;
for(int dir=0;dir<4;dir++)
if(isConflict(i,j,n,dir)) //判断四个方向上是否产生冲突
return false;
return true;
}
int queue(int n)
{
int res=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
int r=randa(0,n-1);
if(vis[i][r]==0 && place(i,r,n)){
vis[i][r]=1;
res++;
}
}
}
return res;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF){
int max=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
scanf(" %c",&map[i][j]);
}
}
for(int t=0;t<1000;t++){
memset(vis,0,sizeof(vis));
int res=queue(n);
if(max<res){
max=res;
}
}
cout<<max<<endl;
}
return 0;
}