4 .X.. .... XX.. .... 2 XX .X 3 .X. X.X .X. 3 ... .XX .XX 4 .... .... .... .... 0
5 1 5 2 4题意:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using
namespace std;/*
int cmp(const void *a,const void
*b){
return
*(int*)a-*(int*)b;
}*/
int count(int a[4][4],int row,int col,int
n){/*数数,计算每个空位,十字架方向上所有能够放的,即会发生冲突的数目*/
int
count1=0,i;/*注意四个方向,count计数,别忘了设初值为0*/
for(i=row-1;i>=0;i--){/*up*/
if(a[i][col]==2)/*碰到墙才会停止*/
break;
else
count1++;
}
for(i=row+1;i<n;i++){/*down*/
if(a[i][col]==2)
break;
else
count1++;
}
for(i=col-1;i>=0;i--){/*left*/
if(a[row][i]==2)
break;
else
count1++;
}
for(i=col+1;i<n;i++){/*right*/
if(a[row][i]==2)
break;
else
count1++;
}
return
count1;
}
bool right(int a[4][4],int row,int col,int
n){/*判断是否可以安置炮*/
int
i;
for(i=row-1;i>=0;i--){/*用bool型*/
if(a[i][col]==1)/*十字架方向上碰到架炮的地方,就说明有冲突,即此处不可行*/
return false;
else
if(a[i][col]==2)/*碰到墙停止*/
break;
}
//down
for(i=row+1;i<n;i++){/*仍旧是四个方向上检测*/
if(a[i][col]==1)
return false;
else
if(a[i][col]==2)
break;
}
//left
for(i=col-1;i>=0;i--){
if(a[row][i]==2)
break;
else
if(a[row][i]==1)
return false;
}
//right
for(i=col+1;i<n;i++){
if(a[row][i]==2)
break;
else
if(a[row][i]==1)
return false;
}
return
true;
}
int main(){
int
n,i,j,k,ans;
char c;
int
map[4][4];
int cnt[4][4];
while(scanf("%d",&n),n){
k=0,ans=0;
memset(cnt,-1,sizeof(cnt));
for(i=0;i<n;i++){
for(j=0;j<n;j++){
//
scanf("%c",&c);
cin>>c;
if(c==‘.‘){/*将字符型的图转化成数组型的*/
k++;/*顺表记录下总共有多少个空的位置,方便最后检测成不成功时的循环次数*/
map[i][j]=0;/*0表示可放的位置*/
}
else
if(c==‘X‘)/*X表示墙的位置*/
map[i][j]=2;
}
}
for(i=0;i<n;i++){/*计数,遇墙跳过,遇空地计数,并将地址与数目用二维数组cnt[i][j]保留下来*/
for(j=0;j<n;j++){
if(map[i][j]==2)
continue;
else
cnt[i][j]=count(map,i,j,n);
}
}
/*qsort(cnt,n*n,sizeof(cnt[0][0]),cmp);//!!!不能使用qsort直接对cnt排序,否则将会把位置给弄丢,所以应该使用冒泡排序*/
int
min=7,mini,minj;/*最多只能是6,用题中的最大可能做最小箱的箱底*/
while(k--){/*有k个空位,即有k种可能性,每个位置都要判断下*/
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(cnt[i][j]==-1)
continue;
else
if(cnt[i][j]<min){/*要先排排序,从最小的开始,使用贪心,因为周围的可能最少,该位成功的可能性最大*/
min=cnt[i][j];/*重置最小*/
mini=i;/*记录位置*/
minj=j;
}
}
}
if(right(map,mini,minj,n)){/*判断是否能够放*/
map[mini][minj]=1;/*可以的话,就将map中的该位置为1,标志为有炮,便于剩下位置的判断*/
ans++;/*成立计数加1*/
}
cnt[mini][minj]=-1;/*该位置不用再检测了,在cnt数组中标记下-1,直接跳过,检测第二个最小的位置*/
min=7;/*重置最小*/
}
/*“。”点表示可放东西,总计有多少个空,k个*/
/*
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(cnt[i][j]==-1)
continue;
else
if(right(map,i,j,n)){
map[i][j]=1;
ans++;
}
}
}*/
printf("%d\n",ans);/*输出*/
}
return 0;
}
原文:http://www.cnblogs.com/money-lady/p/3659076.html