fork(1) download
  1. /* paiza POH! vol.2
  2.  * result:
  3.  * http://p...content-available-to-author-only...a.jp/poh/paizen/result/a3895d6932e604b3683e7feafbf8e98d
  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. List<Position> startposition2left = new ArrayList<Position>(H * W);
  24. List<Position> startposition2top = new ArrayList<Position>(H * W);
  25.  
  26. for (int y = 0; y < H; y++)
  27. {
  28. String line = in.readLine();
  29. int space2leftSize = 0;
  30. for (int x = 0; x < W; x++)
  31. {
  32. char ch = line.charAt(x);
  33. if (ch == '1')
  34. {
  35. space2leftSize = 0;
  36. space2top[y][x] = 0;
  37. if (x > 0 && space2left[y][x - 1] > 0)
  38. {
  39. startposition2left.add(
  40. Position.getPosition(y, x - 1));
  41. }
  42. if (y > 0 && space2top[y - 1][x] > 0)
  43. {
  44. startposition2top.add(
  45. Position.getPosition(y - 1, x));
  46. }
  47. }
  48. else // if (ch == '0')
  49. {
  50. spacecount++;
  51. space2leftSize++;
  52. if (y > 0)
  53. {
  54. space2top[y][x] = space2top[y - 1][x] + 1;
  55. if (y == H - 1)
  56. {
  57. startposition2top.add(
  58. Position.getPosition(y, x));
  59. }
  60. }
  61. else // if (y == 0)
  62. {
  63. space2top[y][x] = 1;
  64. }
  65. if (x == W - 1)
  66. {
  67. startposition2left.add(
  68. Position.getPosition(y, x));
  69. }
  70. }
  71. space2left[y][x] = space2leftSize;
  72. }
  73. }
  74. // print2dArray(space2left);
  75. // print2dArray(space2top);
  76. // System.out.println(startposition2left);
  77. // System.out.println(startposition2top);
  78.  
  79. // 縦横2以上の空所をカウントする
  80. Map<Position, List<Position>> map = new HashMap<Position, List<Position>>();
  81. for (Position position : startposition2left)
  82. {
  83. int spaceWSize = space2left[position.y][position.x];
  84. if (spaceWSize < 2)
  85. {
  86. continue;
  87. }
  88. for (int dx = 0; dx < spaceWSize - 1; dx++)
  89. {
  90. int w = spaceWSize - dx;
  91. int x = position.x - dx;
  92. int spaceHSize = space2top[position.y][x];
  93. if (spaceHSize < 2)
  94. {
  95. continue;
  96. }
  97. List<Position> list = new ArrayList<Position>();
  98. int dy;
  99. for (dy = 1; dy < spaceHSize; dy++)
  100. {
  101. int y = position.y - dy;
  102. int ww = space2left[y][x];
  103. if (ww < w)
  104. {
  105. if (dy > 1)
  106. {
  107. list.add(Position.getPosition(dy, w));
  108. }
  109. if (ww == 1)
  110. {
  111. break;
  112. }
  113. w = ww;
  114. }
  115. }
  116. if (dy == spaceHSize)
  117. {
  118. list.add(Position.getPosition(dy, w));
  119. }
  120. if (list.isEmpty() == false)
  121. {
  122. map.put(Position.getPosition(position.y, x), list);
  123. }
  124. }
  125. }
  126. // System.out.println(map);
  127.  
  128. final int N = Integer.valueOf(in.readLine()); // ウィジェット数
  129. Map<Position, Integer> result = new HashMap<Position, Integer>(N);
  130.  
  131. for (int i = 0; i < N; i++)
  132. {
  133. String[] st = in.readLine().split(" ");
  134. int s = Integer.parseInt(st[0]); // ウィジェットの縦サイズ
  135. int t = Integer.parseInt(st[1]); // ウィジェットの横サイズ
  136. Position key = Position.getPosition(s, t);
  137. Integer value;
  138. if ((value = result.get(key)) != null)
  139. {
  140. System.out.println(value.intValue());
  141. continue;
  142. }
  143. int placeableCount = 0;
  144.  
  145. if (s == 1) // 横長のウィジェット
  146. {
  147. if (t == 1) // 1x1のウィジェット
  148. {
  149. placeableCount = spacecount;
  150. }
  151. else // if (t != 1) // 横長のウィジェット
  152. {
  153. for (Position position : startposition2left)
  154. {
  155. int spaceWSize = space2left[position.y][position.x];
  156. if (spaceWSize >= t)
  157. {
  158. placeableCount += spaceWSize - t + 1;
  159. }
  160. }
  161. }
  162. }
  163. else if (t == 1) // 縦長のウィジェット
  164. {
  165. for (Position position : startposition2top)
  166. {
  167. int spaceHSize = space2top[position.y][position.x];
  168. if (spaceHSize >= s)
  169. {
  170. placeableCount += spaceHSize - s + 1;
  171. }
  172. }
  173. }
  174. else // if (s != 1 && t != 1)
  175. {
  176. for (List<Position> list : map.values())
  177. {
  178. for (Position size : list)
  179. {
  180. if (s <= size.y && t <= size.x)
  181. {
  182. placeableCount++;
  183. break;
  184. }
  185. }
  186. }
  187. }
  188. System.out.println(placeableCount);
  189. result.put(key, Integer.valueOf(placeableCount));
  190. }
  191.  
  192. } // end of main(String[])
  193.  
  194. static void print2dArray(int[][] array)
  195. {
  196. for (int i = 0; i < array.length; i++)
  197. {
  198. for (int j = 0; j < array[i].length; j++)
  199. {
  200. System.out.print(array[i][j] + " ");
  201. }
  202. System.out.println();
  203. }
  204. System.out.println();
  205. }
  206.  
  207. static class Position
  208. {
  209. static Position[] pool = new Position[90000];
  210. static Position getPosition(int y, int x)
  211. {
  212. int index = y * 300 + x;
  213. if (pool[index] == null)
  214. {
  215. pool[index] = new Position(y, x);
  216. }
  217. return pool[index];
  218. }
  219.  
  220. final int y;
  221. final int x;
  222. private Position(int y, int x)
  223. {
  224. this.y = y;
  225. this.x = x;
  226. }
  227.  
  228. @Override public String toString()
  229. {
  230. return "(" + x + ", " + y + ")";
  231. }
  232.  
  233. @Override public int hashCode()
  234. {
  235. return y ^ x;
  236. }
  237.  
  238. @Override public boolean equals(Object obj)
  239. {
  240. Position pos = (Position)obj;
  241. return y == pos.y && x == pos.x;
  242. }
  243. } // end of class Position
  244. }
  245.  
Success #stdin #stdout 0.07s 380224KB
stdin
5 5
00000
00100
00010
10001
10000
3
2 2
1 1
3 2
stdout
6
20
2