记录编号 |
62386 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[NOI 2005]瑰丽华尔兹 |
最终得分 |
100 |
用户昵称 |
cstdio |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.628 s |
提交时间 |
2013-06-25 18:51:38 |
内存使用 |
0.53 MiB |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<deque>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<stack>
#include<vector>
#include<fstream>
using namespace std;
const int SIZEN=210,SIZEK=210,INF=0x7fffffff;
int N,M,K;//N行M列
//这里的行列从1开始
int inx,iny;//初始位置
bool board[SIZEN][SIZEN]={0};//若为1表示有家具
int s[SIZEK]={0},t[SIZEK]={0},d[SIZEK]={0};//描述K个区间
//1上,2下,3左,4右
int f[SIZEN][SIZEN]={0};
void uprow(int k,int len){//对下一个时段第k列进行单调队列递推,方向是从下向上
deque<int> Q;
int f0[SIZEN]={0};
int i,temp;
for(i=1;i<=N;i++) f0[i]=f[i][k];
for(i=N;i>=1;i--){
if(board[i][k]){
Q.clear();
continue;
}
while(Q.size()&&f0[Q.back()]+Q.back()-i<=f0[i]) Q.pop_back();
Q.push_back(i);
temp=Q.front()-i;
if(temp>len) Q.pop_front();
f[i][k]=f0[Q.front()]+Q.front()-i;
}
}
void up(int k){//第k个区间
int i,temp=t[k]-s[k]+1;
for(i=1;i<=M;i++) uprow(i,temp);
}
void downrow(int k,int len){//对下一个时段第k列进行单调队列递推,方向是从上向下
deque<int> Q;
int f0[SIZEN]={0};
int i,temp;
for(i=1;i<=N;i++) f0[i]=f[i][k];
for(i=1;i<=N;i++){
if(board[i][k]){
Q.clear();
continue;
}
while(Q.size()&&f0[Q.back()]+i-Q.back()<=f0[i]) Q.pop_back();
Q.push_back(i);
temp=i-Q.front();
if(temp>len) Q.pop_front();
f[i][k]=f0[Q.front()]+i-Q.front();
}
}
void down(int k){//第k个区间
int i,temp=t[k]-s[k]+1;
for(i=1;i<=M;i++) downrow(i,temp);
}
void leftline(int k,int len){//对下一个时段第k行进行单调队列递推,方向是从右向左
deque<int> Q;
int f0[SIZEN]={0};
int i,temp;
for(i=1;i<=M;i++) f0[i]=f[k][i];
for(i=M;i>=1;i--){
if(board[k][i]){
Q.clear();
continue;
}
while(Q.size()&&f0[Q.back()]+Q.back()-i<=f0[i]) Q.pop_back();
Q.push_back(i);
temp=Q.front()-i;
if(temp>len) Q.pop_front();
f[k][i]=f0[Q.front()]+Q.front()-i;
}
}
void left(int k){//第k个区间
int i,temp=t[k]-s[k]+1;
for(i=1;i<=N;i++) leftline(i,temp);
}
void rightline(int k,int len){//对下一个时段第k行进行单调队列递推,方向是从左向右
deque<int> Q;
int f0[SIZEN]={0};
int i,temp;
for(i=1;i<=M;i++) f0[i]=f[k][i];
for(i=1;i<=M;i++){
if(board[k][i]){
Q.clear();
continue;
}
while(Q.size()&&f0[Q.back()]+i-Q.back()<=f0[i]) Q.pop_back();
Q.push_back(i);
temp=i-Q.front();
if(temp>len) Q.pop_front();
f[k][i]=f0[Q.front()]+i-Q.front();
}
}
void right(int k){//第k个区间
int i,temp=t[k]-s[k]+1;
for(i=1;i<=N;i++) rightline(i,temp);
}
void dp(void){
int i,j;
for(i=1;i<=K;i++){
switch(d[i]){
case 1:up(i);break;
case 2:down(i);break;
case 3:left(i);break;
case 4:right(i);break;
}
}
int ans=-INF;
for(i=1;i<=N;i++){
for(j=1;j<=M;j++) ans=max(ans,f[i][j]);
}
printf("%d\n",ans);
}
void init(void){
scanf("%d%d%d%d%d",&N,&M,&inx,&iny,&K);
int i,j;
char ch;
for(i=1;i<=N;i++){
getchar();
for(j=1;j<=M;j++){
cin>>ch;
board[i][j]=(ch=='x');
}
}
for(i=1;i<=K;i++) scanf("%d%d%d",&s[i],&t[i],&d[i]);
for(i=1;i<=N;i++){
for(j=1;j<=M;j++) f[i][j]=-INF;
}
f[inx][iny]=0;
}
int main(){
freopen("adv1900.in","r",stdin);
freopen("adv1900.out","w",stdout);
init();
dp();
return 0;
}