题目链接:http://codeforces.com/problemset/problem/327/D
题意:给出图的行列n和m,还有一个图,由’.’和’#’组成,分别表示平地和坑,然后现在要在平地上建造东西,给出三种操作,建蓝色房子(可以住100人),建红色房子(可以住200人),摧毁房子,进行这3种操作有分别的要求,建蓝色房子,要求在平地上,建红色房子要求在平地上而且旁边要有一座蓝色房子,摧毁操作可以选择一处房子进行摧毁,摧毁后的地方变成平地。要求让你进行若干次数的操作,使得这一整块地上能住尽可能多的人。输出操作次数和每一次操作。
分析:拿到这道题先画一画,发现可以一直建蓝色房子,直到不能建的时候再建红色房子,然后再原路返回摧毁建成红色房子,这样就以一直满足红色房子的要求而建尽可能多的红房子。所以dfs搞起来。
下面是1Y的代码(牛*坏了,撑会儿腰.jpg):
#include<cstdio>
#include<cstring>
#include<string>
#include<sstream>
#include<iostream>
#include<set>
#include<map>
#include<queue>
#include<deque>
#include<vector>
#include<algorithm>
#include<cctype>
#include<math.h>
#include<stdlib.h>
#include<stack>
#include<ctime>
#define mst(a,b) memset(a,b,sizeof(a))
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
#define pii pair<int,int>
const int N = 1e9;
const int mod=(int)1e9+7;
const int INF=0x3f3f3f3f;
const long long LINF=(1LL<<62);
typedef long long LL;
//#define LOCAL
const double PI = acos(-1.0);
const int maxn=1e5+5;
using namespace std;
char s[505][505];
int ud[4] = {1,0,-1,0};
int lr[4] = {0,1,0,-1};
int n, m;
struct node
{
int x, y;
char oper; //操作种类
node (int x=0, int y=0, char oper=0):x(x),y(y),oper(oper){}
};
queue<node> st; //这里用队列方便对后面的操作(路径)进行输出
bool judge(int x, int y){
if(x<1||x>n||y<1||y>m||s[x][y]=='#') return false;
else return true;
}
void dfs(int x, int y, int ix, int iy) //x,y为当前的位置,ix,iy为起始位置
{
if(x==ix&&y==iy){ //起点的时候就先建一座蓝色的房子
node t1(x,y,'B');
st.push(t1);
s[x][y] = '#'; //把这个地方变成坑,相当于访问过
}
int is = 0;
for(int i = 0; i < 4; i++){ //四个方向
int dx = x+ud[i];
int dy = y+lr[i];
if(judge(dx,dy)){
s[dx][dy] = '#';
int sum = 0;
for(int j = 0; j < 4; j++){ //检验下一个位置的四周是否能再进行操作,如果不能就直接进行建红房子的操作,而不需要建蓝再摧毁。
int ddx = dx+ud[j];
int ddy = dy+lr[j];
if(!judge(ddx,ddy)) sum++;
else break;
}
if(sum==4) {node v(dx,dy,'R'); st.push(v); continue;} //四个方向都有坑(墙),直接建红房子。
node v(dx,dy,'B'); //建蓝色房子,把操作push进队列
st.push(v);
dfs(dx,dy,ix,iy);
}
}
if(x!=ix||y!=iy){ //递归回来的时候进行摧毁,然后建红房子的操作,如果是起点的位置则不用进行操作。
node t1(x,y,'D');
node t2(x,y,'R');
st.push(t1);
st.push(t2);
}
return ;
}
int main()
{
#ifdef LOCAL
freopen("test.txt", "r", stdin);
#endif // LOCAL
//ios::sync_with_stdio(false);
scanf("%d%d", &n, &m);
getchar();
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++) s[i][j] = getchar();
getchar();
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(s[i][j]=='.') dfs(i,j,i,j);
}
}
printf("%d\n", st.size());
while(!st.empty()){ //FIFO贼方便。
node u = st.front(); st.pop();
printf("%c %d %d\n", u.oper, u.x, u.y);
}
return 0;
}
做的出来怕是要归功于寒假刷的专题。
跟大佬的差距还是很大的,要继续加油!!(:з)∠)