fork download
  1. /* paiza POH! vol.2
  2.  * result:
  3.  * http://p...content-available-to-author-only...a.jp/poh/paizen/result/bf7a5ec80e12edba64c30dabdd93a807
  4.  * author: Leonardone @ NEETSDKASU
  5.  */
  6. import java.util.*;
  7. import java.lang.*;
  8. import java.io.*;
  9.  
  10. class Main
  11. {
  12. public static void main (String[] args) throws java.lang.Exception
  13. {
  14.  
  15. String[] hw = in.readLine().split(" ");
  16. final int H = Integer.parseInt(hw[0]); // ホーム画面縦の区画数
  17. final int W = Integer.parseInt(hw[1]); // ホーム画面横の区画数
  18.  
  19. int[][] space2left = new int[H][W];
  20. int[][] space2top = new int[H][W];
  21. int spacecount = 0;
  22.  
  23. Position[] startposition2left = new Position[H * W];
  24. Position[] startposition2top = new Position[H * W];
  25. int splCount = 0;
  26. int sptCount = 0;
  27.  
  28. for (int y = 0; y < H; y++)
  29. {
  30. String line = in.readLine();
  31. int space2leftSize = 0;
  32. for (int x = 0; x < W; x++)
  33. {
  34. char ch = line.charAt(x);
  35. if (ch == '1')
  36. {
  37. space2leftSize = 0;
  38. space2top[y][x] = 0;
  39. if (x > 0 && space2left[y][x - 1] > 0)
  40. {
  41. startposition2left[splCount++] =
  42. Position.getPosition(y, x - 1);
  43. }
  44. if (y > 0 && space2top[y - 1][x] > 0)
  45. {
  46. startposition2top[sptCount++] =
  47. Position.getPosition(y - 1, x);
  48. }
  49. }
  50. else // if (ch == '0')
  51. {
  52. spacecount++;
  53. space2leftSize++;
  54. if (y > 0)
  55. {
  56. space2top[y][x] = space2top[y - 1][x] + 1;
  57. if (y == H - 1)
  58. {
  59. startposition2top[sptCount++] =
  60. Position.getPosition(y, x);
  61. }
  62. }
  63. else // if (y == 0)
  64. {
  65. space2top[y][x] = 1;
  66. }
  67. if (x == W - 1)
  68. {
  69. startposition2left[splCount++] =
  70. Position.getPosition(y, x);
  71. }
  72. }
  73. space2left[y][x] = space2leftSize;
  74. }
  75. }
  76. // print2dArray(space2left);
  77. // print2dArray(space2top);
  78. // System.out.println(startposition2left);
  79. // System.out.println(startposition2top);
  80.  
  81. final int N = Integer.valueOf(in.readLine()); // ウィジェット数
  82. HashSet<Position> placeablePosition = new HashSet<Position>(H * W);
  83. Map<Position, Integer> result = new HashMap<Position, Integer>(N);
  84.  
  85. for (int i = 0; i < N; i++)
  86. {
  87. String[] st = in.readLine().split(" ");
  88. int s = Integer.parseInt(st[0]); // ウィジェットの縦サイズ
  89. int t = Integer.parseInt(st[1]); // ウィジェットの横サイズ
  90. Position key = Position.getPosition(s, t);
  91. Integer value;
  92. if ((value = result.get(key)) != null)
  93. {
  94. System.out.println(value.intValue());
  95. continue;
  96. }
  97. int placeableCount = 0;
  98.  
  99. if (s == 1) // 横長のウィジェット
  100. {
  101. if (t == 1) // 1x1のウィジェット
  102. {
  103. placeableCount = spacecount;
  104. }
  105. else // if (t != 1) // 横長のウィジェット
  106. {
  107. for (int spl = 0; spl < splCount; ++spl)
  108. {
  109. Position position = startposition2left[spl];
  110. int spaceWSize = space2left[position.y][position.x];
  111. if (spaceWSize >= t)
  112. {
  113. placeableCount += spaceWSize - t + 1;
  114. }
  115. }
  116. }
  117. }
  118. else if (t == 1) // 縦長のウィジェット
  119. {
  120. for (int spt = 0; spt < sptCount; ++spt)
  121. {
  122. Position position = startposition2top[spt];
  123. int spaceHSize = space2top[position.y][position.x];
  124. if (spaceHSize >= s)
  125. {
  126. placeableCount += spaceHSize - s + 1;
  127. }
  128. }
  129. }
  130. else // if (s != 1 && t != 1)
  131. {
  132. placeablePosition.clear();
  133. // 横に走査していく
  134. for (int spl = 0; spl < splCount; ++spl)
  135. {
  136. Position position = startposition2left[spl];
  137. int spaceWSize = space2left[position.y][position.x];
  138. for (int dx = 0; dx < spaceWSize; ++dx)
  139. {
  140. int x = position.x - dx;
  141. int spaceHSize = space2top[position.y][x];
  142. if (spaceHSize < s)
  143. {
  144. continue; // 縦サイズが足りない
  145. }
  146. // 縦に走査して横サイズ以上の連続する空所を数える
  147. int count = 0;
  148. for (int dy = 0; dy < spaceHSize; ++dy)
  149. {
  150. int y = position.y - dy;
  151. if (space2left[y][x] >= t)
  152. {
  153. count++;
  154. if (count >= s) // ウィジェットが確保できる
  155. {
  156. boolean placed = placeablePosition.add(
  157. Position.getPosition(y, x));
  158. if (placed == false)
  159. {
  160. break; // これ以上の縦の走査は走査済み
  161. }
  162. }
  163. }
  164. else
  165. {
  166. count = 0; // 連続の途切れ
  167. }
  168. }
  169. }
  170. }
  171. placeableCount = placeablePosition.size();
  172. }
  173. System.out.println(placeableCount);
  174. result.put(key, Integer.valueOf(placeableCount));
  175. }
  176.  
  177. } // end of main(String[])
  178.  
  179. static void print2dArray(int[][] array)
  180. {
  181. for (int i = 0; i < array.length; i++)
  182. {
  183. for (int j = 0; j < array[i].length; j++)
  184. {
  185. System.out.print(array[i][j] + " ");
  186. }
  187. System.out.println();
  188. }
  189. System.out.println();
  190. }
  191.  
  192. static class Position
  193. {
  194. static Position[] pool = new Position[90000];
  195. static Position getPosition(int y, int x)
  196. {
  197. int index = y * 300 + x;
  198. if (pool[index] == null)
  199. {
  200. pool[index] = new Position(y, x);
  201. }
  202. return pool[index];
  203. }
  204.  
  205. final int y;
  206. final int x;
  207. private Position(int y, int x)
  208. {
  209. this.y = y;
  210. this.x = x;
  211. }
  212.  
  213. @Override public String toString()
  214. {
  215. return "(" + x + ", " + y + ")";
  216. }
  217.  
  218. @Override public int hashCode()
  219. {
  220. return y ^ x;
  221. }
  222.  
  223. @Override public boolean equals(Object obj)
  224. {
  225. Position pos = (Position)obj;
  226. return y == pos.y && x == pos.x;
  227. }
  228. } // end of class Position
  229. }
  230.  
Success #stdin #stdout 0.08s 380160KB
stdin
5 5
00000
00100
00010
10001
10000
3
2 2
1 1
3 2
stdout
6
20
2