/*炸弹人
# 代表墙体
.代表可以安放地雷的地方
G代表敌人 地雷会朝着横向竖向炸去 遇到墙体结束
输入起点位置 求可以炸掉最多敌人的坐标
*/
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# define H 30//地图尺寸行数
# define L 45//地图尺寸列数
const int NEXT[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//四个用来模拟 向右 向下 向左 向上
char CHO[]={"#..GG"};
char MAP[H][L+1];//用来储存地图的字符数组
char SSS[]={"012345678901234567890123456789012345678901234567890"};
int hh,ll;
int getsum(char MAP[][L+1],int X,int Y);
int gainint(int *p,int a,int b);//输入int *p直至满足(a,b)输入结束,并返回*p
int main(){
int queue[H*L][2]={0},head=1,tail=1;//用二维数组模拟队列 quque[0][]储存横坐标 queue[1][]存纵坐标
int BOOK[H+1][L+1]={0},X,Y,SUM,MAX=0,i,TX,TY,j,k;//BOOK是用来标记的数组 初始化为0 BX BY是begin初始的位置
/****************此处只是生成随机地图可以不看*********************/
srand(time(NULL));
printf("输入地图行数∈[4,%d]:",H);
gainint(&hh,4,H);
printf("输入地图宽度∈[6,%d]:",L);
gainint(&ll,6,L);
SSS[ll]='\0';
system("cls");
for(i=0;i<hh;i++)
{
printf("%02d",i);
for(j=0;j<ll;j++)
{
if(i==0&&j==0)
printf("%s-------->Y\n00",SSS);
if(i==0||i==hh-1||j==0||j==ll-1)
MAP[i][j]=CHO[0];
else
MAP[i][j]=CHO[rand()%5];
printf("%c",MAP[i][j]);
}
printf("\n");
}
printf("|\n|\nX\n");
/*********************随机地图生成完毕**************8*/
do{
printf("输入起始位置(X,Y):");
scanf("%d %d",&X,&Y);
while(getchar()!='\n');
if(MAP[X][Y]!='.')
printf("输入位置不空闲,请重新");
}while(MAP[X][Y]!='.');
queue[tail][0]=X; //现将初始坐标压入队列
queue[tail++][1]=Y; //
BOOK[X][Y]=1; //标记当前已经走过该点
MAX=getsum(MAP,X,Y); //计算此点的可炸掉的敌人的个数
while(head<tail) //当队列不为空时
{
for(i=0;i<4;i++) //枚举四个方向
{
TX=queue[head][0]+NEXT[i][0];
TY=queue[head][1]+NEXT[i][1];
if(TX<0||TX>hh-1||TY<0||TY>ll-1) //判断是否出界
continue;
if(MAP[TX][TY]=='.'&&!BOOK[TX][TY])//对其判断是否可以安放地雷 并且没走过
{
BOOK[TX][TY]=1; //标记当前已经走过
queue[tail][0]=TX; //压入队列
queue[tail++][1]=TY;
SUM=getsum(MAP,TX,TY); //计算此前的可炸掉的敌人数量
if(SUM>MAX) //如果炸掉的敌人数量比之前计算得多
{
MAX=SUM; //更新最大值
X=TX;
Y=TY;
}
}
}
head++; //队头加一进行点的拓展
}
system("cls");
MAP[X][Y]='&';
for(i=0;i<hh;i++)
{
printf("%02d",i);
for(j=0;j<ll;j++)
{
if(i==0&&j==0)
printf("%s-------->Y\n00",SSS);
printf("%c",MAP[i][j]);
}
printf("\n");
}
printf("|\n|\nX\n");
printf("炸弹放在(%d,%d)处(地图上标有*的地方) \n最多会消灭%d个敌人.\n",X,Y,MAX);
return 0;
}
int getsum(char MAP[][L+1],int X,int Y)
{
int sum=0,xx,yy,i,T[]={-1,1};
for(i=0;i<4;i++) //四次循环用于计算地雷的总个数
{
xx=X;yy=Y;
while(MAP[xx][yy]!='#') //当没有遇到墙体
{
if(MAP[xx][yy]=='G')//如果是敌人
++sum;
if(i<2)
xx+=T[i%2]; //四个方向的判断
else yy+=T[i%2];
}
}
return sum; //返回sum
}
int gainint(int *p,int a,int b)//输入int *p直至满足(a,b)输入结束,并返回*p
{
do{
*p=a-1;
scanf("%d",p);
while(getchar()!='\n');
if(*p>b||*p<a)
printf("输入有误,请重新输入(%d--%d):\n",a,b);
}while(*p>b||*p<a);
return *p;
}
附加小程序:
# include <stdio.h>
# include <string.h>
# define N 100 //如果想录入x个字节那么就把N的数值改成x
int gainchar(char *A,int min,int max);
int gainint(int *p,int a,int b);
void paixu(char *a[],int n,int F);
void main(){
int n,F,i;
char B[N][N+1],*P[N],S[][3]={"升","降"};
do{
printf("输入要录入的字符串个数[2,%d]:",N);
gainint(&n,2,N);
for(i=0;i<n;i++)
{
printf("第%d个字符串,字节--[1,%d]:",N);
gainchar(B[i],1,N);
P[i]=B[i];//让每个指针指向每个字符数组
}
printf("升序请按0:降序请按1--[0,1]:");
gainint(&F,0,1);
paixu(P,n,F);
printf("%s后:\n",S[F]);
for(i=0;i<n;i++)
printf("%s\n",P[i]);
}while(1);
}
int gainint(int *p,int a,int b)//输入int *p直至满足[a,b]输入结束,返回*p
{
do{
*p=a-1;
scanf("%d",p);
while(getchar()!='\n');
if(*p>b||*p<a)
printf("输入有误,请重新输入(%d--%d):\n",a,b);
}while(*p>b||*p<a);
return *p;
}
int gainchar(char *A,int min,int max)//长度在[min,max] <闭区间> 之间时 函数结束 返回字符串A的长度
{
int B,C;
do{
A[max]=B=C=0;
while((A[B++]=getchar())!='\n'&&B<max);
if(A[B-1]!='\n')
while(getchar()!='\n'&&++C);
else A[--B]=0;
if(C||B&&B<min)
printf("您录入的字符串长度:%d字节\n只录入(%d--%d)个字节!\n",B+C,min,max);
}while(C||B<min);
return B;
}
void paixu(char *a[],int n,int F)
{
int i,j,k,Y;
char *temp;
for(i=0;i<n-1;i++)
{
k=i;
for(j=i+1;j<n;j++)
{
Y=strcmp(a[j],a[k]);
if(F?Y<0:Y>0) //b=0升序 b为其他降序
k=j;
}
if(k!=i)
{
temp=a[k];
a[k]=a[i];
a[i]=temp;
}
}
}
以上是用字符数组节省交换的时间
# include <stdio.h>
/*查昊昊:输入字符个数 然后输入字符串 对字符串进行升序或降序排列*/
# define N 101 //如果想录入x个字节那么就把N的数值改成x+1
int gainint(int *p,int a,int b);//返回数字的位数
int gainchar(char *a,int min,int max);//返回字符长度
void paixu(char a[],int n,int b);
void main(){
int n,c,i,d;
char B[N],S[][3]={"升","降"};
do{
printf("请输入字符串长度(2--%d):",N-1);
gainint(&n,2,N-1);
printf("输入字符串:\n");
c=gainchar(B,n,n+1);
printf("原字符串:\n%s\n",B);
for(i=0;i<2;i++)
{
printf("%s序:\n",S[i]);
paixu(B,c,i);
printf("%s\n",B);
}
}while(1);
}
int gainint(int *p,int a,int b)//p相当于地址,在主函数中传入&a,就是把a的地址传到函数里,那么在函数里就可以改变a的值了
{
int c[2]={0,1};
do{
scanf("%d",p);
while(getchar()!='\n');
if(*p>b||*p<a)
printf("输入有误,请重新输入(%d--%d):",a,b);
}while(*p>b||*p<a);
return *p;
}
int gainchar(char *a,int min,int max)//对*a输入范围(min,max),如果字符数组中存在'\n',将其改为'\0'
{
int c;
do{
c=-1;
fgets(a,max,stdin);
while(a[++c]);
c=a[c-1]=='\n'&&c<max?c-1:c;
if(c>=max-1)
while(getchar()!='\n');
else
a[c]='\0';
if(c&&(c>max||c<min))//如果用户只输入'\n'则不提示输入错误,否则提示错误
printf("输入有误,请重新输入只录入(%d--%d)字节:\n",min,max-1);
}while(c>max||c<min);
return c;
}
void paixu(char a[],int n,int b)
{
int i,j,k,temp;
for(i=0;i<n-1;i++)
{
k=i;
for(j=i+1;j<n;j++)
if(b?a[j]>a[k]:a[j]<a[k]) //b=0升序 b为其他降序
k=j;
if(k!=i)
{
temp=a[k];
a[k]=a[i];
a[i]=temp;
}
}
}