记录编号 62386 评测结果 AAAAAAAAAA
题目名称 [NOI 2005]瑰丽华尔兹 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.628 s
提交时间 2013-06-25 18:51:38 内存使用 0.53 MiB
显示代码纯文本
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<deque>
  5. #include<cmath>
  6. #include<iomanip>
  7. #include<cstring>
  8. #include<stack>
  9. #include<vector>
  10. #include<fstream>
  11. using namespace std;
  12. const int SIZEN=210,SIZEK=210,INF=0x7fffffff;
  13. int N,M,K;//N行M列
  14. //这里的行列从1开始
  15. int inx,iny;//初始位置
  16. bool board[SIZEN][SIZEN]={0};//若为1表示有家具
  17. int s[SIZEK]={0},t[SIZEK]={0},d[SIZEK]={0};//描述K个区间
  18. //1上,2下,3左,4右
  19. int f[SIZEN][SIZEN]={0};
  20. void uprow(int k,int len){//对下一个时段第k列进行单调队列递推,方向是从下向上
  21. deque<int> Q;
  22. int f0[SIZEN]={0};
  23. int i,temp;
  24. for(i=1;i<=N;i++) f0[i]=f[i][k];
  25. for(i=N;i>=1;i--){
  26. if(board[i][k]){
  27. Q.clear();
  28. continue;
  29. }
  30. while(Q.size()&&f0[Q.back()]+Q.back()-i<=f0[i]) Q.pop_back();
  31. Q.push_back(i);
  32. temp=Q.front()-i;
  33. if(temp>len) Q.pop_front();
  34. f[i][k]=f0[Q.front()]+Q.front()-i;
  35. }
  36. }
  37. void up(int k){//第k个区间
  38. int i,temp=t[k]-s[k]+1;
  39. for(i=1;i<=M;i++) uprow(i,temp);
  40. }
  41. void downrow(int k,int len){//对下一个时段第k列进行单调队列递推,方向是从上向下
  42. deque<int> Q;
  43. int f0[SIZEN]={0};
  44. int i,temp;
  45. for(i=1;i<=N;i++) f0[i]=f[i][k];
  46. for(i=1;i<=N;i++){
  47. if(board[i][k]){
  48. Q.clear();
  49. continue;
  50. }
  51. while(Q.size()&&f0[Q.back()]+i-Q.back()<=f0[i]) Q.pop_back();
  52. Q.push_back(i);
  53. temp=i-Q.front();
  54. if(temp>len) Q.pop_front();
  55. f[i][k]=f0[Q.front()]+i-Q.front();
  56. }
  57. }
  58. void down(int k){//第k个区间
  59. int i,temp=t[k]-s[k]+1;
  60. for(i=1;i<=M;i++) downrow(i,temp);
  61. }
  62. void leftline(int k,int len){//对下一个时段第k行进行单调队列递推,方向是从右向左
  63. deque<int> Q;
  64. int f0[SIZEN]={0};
  65. int i,temp;
  66. for(i=1;i<=M;i++) f0[i]=f[k][i];
  67. for(i=M;i>=1;i--){
  68. if(board[k][i]){
  69. Q.clear();
  70. continue;
  71. }
  72. while(Q.size()&&f0[Q.back()]+Q.back()-i<=f0[i]) Q.pop_back();
  73. Q.push_back(i);
  74. temp=Q.front()-i;
  75. if(temp>len) Q.pop_front();
  76. f[k][i]=f0[Q.front()]+Q.front()-i;
  77. }
  78. }
  79. void left(int k){//第k个区间
  80. int i,temp=t[k]-s[k]+1;
  81. for(i=1;i<=N;i++) leftline(i,temp);
  82. }
  83. void rightline(int k,int len){//对下一个时段第k行进行单调队列递推,方向是从左向右
  84. deque<int> Q;
  85. int f0[SIZEN]={0};
  86. int i,temp;
  87. for(i=1;i<=M;i++) f0[i]=f[k][i];
  88. for(i=1;i<=M;i++){
  89. if(board[k][i]){
  90. Q.clear();
  91. continue;
  92. }
  93. while(Q.size()&&f0[Q.back()]+i-Q.back()<=f0[i]) Q.pop_back();
  94. Q.push_back(i);
  95. temp=i-Q.front();
  96. if(temp>len) Q.pop_front();
  97. f[k][i]=f0[Q.front()]+i-Q.front();
  98. }
  99. }
  100. void right(int k){//第k个区间
  101. int i,temp=t[k]-s[k]+1;
  102. for(i=1;i<=N;i++) rightline(i,temp);
  103. }
  104. void dp(void){
  105. int i,j;
  106. for(i=1;i<=K;i++){
  107. switch(d[i]){
  108. case 1:up(i);break;
  109. case 2:down(i);break;
  110. case 3:left(i);break;
  111. case 4:right(i);break;
  112. }
  113. }
  114. int ans=-INF;
  115. for(i=1;i<=N;i++){
  116. for(j=1;j<=M;j++) ans=max(ans,f[i][j]);
  117. }
  118. printf("%d\n",ans);
  119. }
  120. void init(void){
  121. scanf("%d%d%d%d%d",&N,&M,&inx,&iny,&K);
  122. int i,j;
  123. char ch;
  124. for(i=1;i<=N;i++){
  125. getchar();
  126. for(j=1;j<=M;j++){
  127. cin>>ch;
  128. board[i][j]=(ch=='x');
  129. }
  130. }
  131. for(i=1;i<=K;i++) scanf("%d%d%d",&s[i],&t[i],&d[i]);
  132. for(i=1;i<=N;i++){
  133. for(j=1;j<=M;j++) f[i][j]=-INF;
  134. }
  135. f[inx][iny]=0;
  136. }
  137. int main(){
  138. freopen("adv1900.in","r",stdin);
  139. freopen("adv1900.out","w",stdout);
  140. init();
  141. dp();
  142. return 0;
  143. }