50095106扔核弹
50095106扔核弹
【试题描述】
21xx年,ussr与us爆发了战争,us想将ussr肢解,于是毫不犹豫的准备使用战略核导弹。你现在正是战略打击部队的司令官,你收到了一幅由卫星发送的加密图片(n*m大小),在这张图片中“.”代表空地,“G”代表敌方军队,“#”代表三防(防核武,防化武,防自然威胁)设施。你的核弹当量极大,可以消灭杀伤范围内所有的暴徒。但你的核弹只能投送到空地上,且如果遇到了三防设施则不再构成杀伤范围(横着一行,竖着一行,碰到三防设施就不构成杀伤范围)。现在你的导弹发射架在(3,3)位置上,为了起到肢解效果,请你输出杀伤暴徒最多的方案,和最多可以杀死暴徒的个数(邪恶......)。
【输入要求】
* 第一行:两个整数n,m。
* 接下来是一张由“G”“#”“.”所构成的一张图,代表卫星发回的地图。
【输出要求】
一句话如下格式
将导弹投送到(x,y),最多可以消灭z个敌人。
【输入实例】
13 13 ############# #GG.GGG#GGG.# ###.#G#G#G#G# #.......#..G# #G#.###.#G#G# #GG.GGG.#.GG# #G#.#G#.#.#.# ##G...G.....# #G#.#G###.#G# #...G#GGG.GG# #G#.#G#G#.#G# #GG.GGG#G.GG# #############
【输出实例】
将导弹投送到(7,11),最多可以消灭10个敌人。
【其他说明】
LJX认为n与m不会大于26。
【试题分析】
LJX李家鑫小朋友出的数据貌似有点坑,输出的格式在中英文上面很复杂~~~
我们先来看一看怎么求投掷在一个点消灭的敌人吧,当然,四个简单的while就能解决,代码如下:
int res(int i,int j) { int sum=0,l,b; l=i;//这里一定不要忘了备份,否则i和j的值以后就不能用了。 b=j; while(a[l][b]!='#')//当不是三防设施的时候 { if(a[l][b]=='G') sum++;//是敌人,sum加1 b++;//威力向左移动 } l=i;//备份 b=j; while(a[l][b]!='#') { if(a[l][b]=='G') sum++; b--;//向右移动 } l=i;//备份 b=j; while(a[l][b]!='#') { if(a[l][b]=='G') sum++; l++;//向上移动 } l=i; b=j; while(a[l][b]!='#') { if(a[l][b]=='G') sum++; l--; }//向下移动 return sum;//返回结果 }
这就可以了。
然后,暴力搜索一遍:
int main() { for(int i=0;i<n;i++)//枚举每一个点 for(int j=0;j<m;j++) { sum=res(i,j); ans=max(ans,sum);//如果结果大就替换 } cout<<ans; }
把这两段代码合起来,再加上声明和头文件and输出格式就对了
对吗?
也许你已经看出漏洞来了,如果只是单单投送到任意空地上的话,那么答案貌似就不是点(7,11)了吧?
可以试着运行一下上面这个程序,还要加上记录点,貌似是右上角那个空地,能消灭11个敌人。
实际上,这还是一个迷宫问题,当然,我们可以用dfs搞定,代码如下:
void dfs(int x,int y) { int next[4][2]={{0,1},//走向数组 {1,0}, {0,-1}, {-1,0}}; int sum,tx,ty,k; sum=res(x,y);//求出打在这里的答案 if(sum>maxn)//大了的话替换 { maxn=sum; mx=x; my=y; } for(k=0;k<=3;k++) { tx=x+next[k][0]; ty=y+next[k][1]; if(tx<0 || tx>n-1 || ty<0 || ty>m-1) continue;//边界判断 if(a[tx][ty]=='.' && book[tx][ty]==0)//可以走且没走到过 { book[tx][ty]=1;//标记已走 dfs(tx,ty);//继续行走 } } return ; }
【代码】
#include<iostream> using namespace std; char a[50][50]; int maxn=-10000,book[50][50],n,m,mx,my; int res(int i,int j) { int sum=0,l,b; l=i; b=j; while(a[l][b]!='#') { if(a[l][b]=='G') sum++; b++; } l=i; b=j; while(a[l][b]!='#') { if(a[l][b]=='G') sum++; b--; } l=i; b=j; while(a[l][b]!='#') { if(a[l][b]=='G') sum++; l++; } l=i; b=j; while(a[l][b]!='#') { if(a[l][b]=='G') sum++; l--; } return sum; } void dfs(int x,int y) { int next[4][2]={{0,1}, {1,0}, {0,-1}, {-1,0}}; int sum,tx,ty,k; sum=res(x,y); if(sum>maxn) { maxn=sum; mx=x; my=y; } for(k=0;k<=3;k++) { tx=x+next[k][0]; ty=y+next[k][1]; if(tx<0 || tx>n-1 || ty<0 || ty>m-1) continue; if(a[tx][ty]=='.' && book[tx][ty]==0) { book[tx][ty]=1; dfs(tx,ty); } } return ; } int main() { int i,startx=3,starty=3; cin>>n>>m; for(int i=0;i<n;i++) for(int j=0;j<m;j++) cin>>a[i][j]; book[startx][starty]=1; maxn=res(startx,starty); mx=3; my=3; dfs(3,3); cout<<"将导弹投送到("<<mx<<","<<my<<"),最多可以消灭"<<maxn<<"个敌人。"; }
你——悟到了么?