poj 2312 Battle City
思路:从Y到T的最小turn。turn:走一步路算一种,开炮也算一种。
B:土墙,可以被炮打坏,打坏以后就不在了。
R:河流,不能通过。
S:铁墙:不能通过,也不能被炮弹打坏。
E:空格,可以直接走过去。
因此,用优先队列,每次取出turn最小的那个,进行操作。知道走到T为止。因为土墙可以仙贝打坏,在通过,因此如果遇到土墙,可以认为进项了两个turn,
而遇到E空格是,只需走一步,进行一个turn
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int cnv[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
struct Rac{
int x,y,cnt;
bool operator < (const Rac & p) const{
return cnt > p.cnt;
} //优先取cnt 最小的那个元素
};
char mp[305][305];
int visit[305][305];
int sx,sy,tx,ty;
int n,m;
int main()
{
while(scanf("%d %d",&m,&n),m!=0||n!=0)
{
getchar();
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
scanf("%c",&mp[i][j]);
if(mp[i][j]=='Y')
{
sx=i;
sy=j;
}
else if(mp[i][j]=='T')
{
tx=i;
ty=j;
}
}
getchar();
} //找出终点,起点
/* for(i=0;i<m;i++)
{
puts(mp[i]);
}*/
memset(visit,0,sizeof(visit));
priority_queue<Rac>q;//优先队列
Rac s;
s.x=sx;
s.y=sy;
s.cnt=0;
visit[sx][sy]=1;
q.push(s);
bool ok=false;
while(!ok&&q.empty()==false) //到达T 或队列为空是,停止
{
Rac t=q.top();
q.pop();
for(i=0;i<4;i++) //上下左右操作
{
int x=t.x+cnv[i][0];
int y=t.y+cnv[i][1];
if(x>=0&&x<m&&y>=0&&y<n&&visit[x][y]==0&&mp[x][y]!='S'&&mp[x][y]!='R')//到达边界&&铁墙或河流不能通过
{
if(mp[x][y]=='E') //为空格时
{
visit[x][y]=1;
Rac t2;
t2.x=x;
t2.y=y;
t2.cnt=t.cnt+1;
q.push(t2);
}
else if(mp[x][y]=='B') //土墙时
{
visit[x][y]=1;
Rac t2;
t2.x=x;
t2.y=y;
t2.cnt=t.cnt+2;
q.push(t2);
}
else if(mp[x][y]=='T') //到达终点
{
ok=true;
printf("%d\n",t.cnt+1);
break;
}
}//if4
}
}
if(!ok) printf("-1\n"); //不能到达
}
return 0;
}
codeforces723DLakes in Berland
给出一个地图:.是水,*是陆地,地图外边是海。这样里边就有湖泊,淡然与海相连的水就不是湖泊。问我要填掉一些湖泊,使得剩下的湖泊个数恰好为k,问最少要填多少水。
首先先DBS扫一次,把每个湖泊的面积以及“起始位置”记录下来。然后如果是与还相连的湖泊就吧大的面积看成极大值inf,然后这样从面积最小的开始填,使得剩下的非inf的湖泊个数恰好为k个。然后从“起始位置”再BFS扫一次把水给填上。最后输出最后的地图。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#include<set>
#define pi acos(-1.0)
#define EPS 1e-6 //log(x)
#define e exp(1.0); //2.718281828
#define mod 1000000007
#define INF 0x7fffffff
#define inf 0x3f3f3f3f
typedef long long LL;
using namespace std;
int n,m,k;
char mp[55][55];
int x[4]={0,0,1,-1};
int y[4]={1,-1,0,0};
bool visit[55][55];
struct wei{
int x,y;
};
struct jilu{ //用于记录湖泊信息
int x,y; //位置
int cnt;//面积
bool operator < (const jilu & p) const{
return cnt<p.cnt;
}
}K[2500];
int jilucnt;
queue<wei>Q;
void bfs(int i,int j){//扫出每个湖泊的面积以及起始位置
while(Q.empty()==false) Q.pop();
int cnt=1;
visit[i][j]=true;
bool ishai=false;
wei temp;
temp.x=i;temp.y=j;
Q.push(temp);
while(Q.empty()==false){
wei temp2=Q.front();
Q.pop();
for(int i=0;i<4;i++){
int nowx=temp2.x+x[i];
int nowy=temp2.y+y[i];
if(nowx<0||nowx>=n||nowy<0||nowy>=m){
ishai=true;
continue;
}
if(mp[nowx][nowy]=='.'&&visit[nowx][nowy]==false){
wei in;
in.x=nowx;
in.y=nowy;
Q.push(in);
cnt++;
visit[nowx][nowy]=true;
}
}
}
K[jilucnt].x=i;
K[jilucnt].y=j;
if(ishai==true)K[jilucnt].cnt=inf;
else K[jilucnt].cnt=cnt;
jilucnt++;
}
queue<wei>tian;
void BFS2(int i,int j){ //填水BFS
while(tian.empty()==false) tian.pop();
wei temp;
temp.x=i;temp.y=j;
tian.push(temp);
while(tian.empty()==false){
wei temp2=tian.front();
tian.pop();
for(int i=0;i<4;i++){
int nowx=temp2.x+x[i];
int nowy=temp2.y+y[i];
if(nowx<0||nowx>=n||nowy<0||nowy>=m){
continue;
}
if(mp[nowx][nowy]=='.'){
wei tempp;
tempp.x=nowx;
tempp.y=nowy;
tian.push(tempp);
}
}
mp[temp2.x][temp2.y]='*';
}
}
int main(){
scanf("%d %d %d",&n,&m,&k);
for(int i=0;i<n;i++) scanf("%s",&mp[i]);
memset(visit,false,sizeof(visit));
jilucnt=0;
for(int i=0;i<=n;i++){
for(int j=0;j<m;j++){
if(mp[i][j]=='.'&&visit[i][j]==false){
//cout<<i<<" "<<j<<endl;
bfs(i,j);
}
}
}
sort(K,K+jilucnt);
//for(int i=0;i<jilucnt;i++) cout<<K[i].cnt<<" "<<K[i].x<<" "<<K[i].y<<endl;
while(K[jilucnt-1].cnt==inf) jilucnt--;
int ans=0;
for(int i=0;i<jilucnt-k;i++){
DFS2(K[i].x,K[i].y);
ans+=K[i].cnt;
}
cout<<ans<<endl;
for(int i=0;i<n;i++) puts(mp[i]);
return 0;
}