Guest User

Untitled

a guest
Aug 15th, 2018
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.87 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #define MAX 987654321
  4. #define WIRE -1
  5. #define CORE 1
  6.  
  7. using namespace std;
  8.  
  9. typedef struct Core {
  10. int y, x;
  11. // 벽에 붙어있으면 true,
  12. // 벽에 떨어져있으면 false
  13. bool wall;
  14. Core() {}
  15. Core(int y_, int x_, bool wall_) : y(y_), x(x_), wall(wall_) {}
  16. };
  17.  
  18. vector<vector<int>> map;
  19. vector<Core> core;
  20. int n, ansConnect, ansWire;
  21. int dy[] = { 0, 1, 0, -1 };
  22. int dx[] = { 1, 0, -1, 0 };
  23.  
  24. bool move(int y, int x ,int dir, int sum, int& ncnt, int remove) {
  25. int cnt = 0;
  26. while(1) {
  27. y = y + dy[dir];
  28. x = x + dx[dir];
  29.  
  30. // 아... 조건... 조건을 잘 검토하자....
  31. // 범위를 넘어가면 가장자리까지 연결성공, 반복문 종료하고 true 리턴
  32. if (y < 0 || x < 0 || y > n - 1 || x > n - 1) break;
  33.  
  34. // 전선깔기
  35. if (sum == -1)
  36. //다음 좌표에 코어가 있거나 전선이 있으면 연결 실패
  37. if (map[y][x] == CORE || map[y][x] == WIRE) return false;
  38.  
  39. // 전선복구
  40. if (sum == 1)
  41. // cnt와 remove가 같으면 이동한 만큼 전선복구 완료
  42. if (cnt == remove) return false;
  43.  
  44. // suum이 -1 이면 전선 까는것, 1이면 이전상태로 복구
  45. map[y][x] += sum; ncnt = cnt = (cnt + 1);
  46. }
  47. return true;
  48. }
  49.  
  50. void dfs(int idx, int connect, int cnt) {
  51. // idx는 코어의 번호
  52. if (idx == core.size()) {
  53. // 전선의 길이 구하기
  54. if (connect >= ansConnect) {
  55. if (connect == ansConnect) ansWire = (cnt < ansWire ? cnt : ansWire);
  56. else { ansConnect = connect; ansWire = cnt; }
  57. }
  58. return;
  59. }
  60.  
  61. // 벽에 붙어있으면 4방향 검사안하고 다음 코어로 이동
  62. if (core[idx].wall) dfs(idx + 1, connect + 1, cnt);
  63.  
  64. // 4방향 탐색하면서 전선 쭉죾 넘기기
  65. else {
  66. int check = 0;// 4방향 탐색
  67. for (int j = 0; j < 4; j++) {
  68. int ncnt = 0;
  69. // 전선연결 성공하면 다음 core로 이동
  70. if (move(core[idx].y, core[idx].x, j, -1, ncnt, 0))
  71. // ncnt + cnt = 이동한 전선의 길이 + 이동전 전선의 길이
  72. dfs(idx + 1, connect + 1, ncnt + cnt);
  73.  
  74. // 전선연결 실패하면 check 1더해줌
  75. else check += 1;
  76.  
  77. //전선 복구
  78. // ncnt는 이동한 전선의 길이, ncnt만큼 -1을 0으로 바꿔줌
  79. move(core[idx].y, core[idx].x, j, 1, ncnt, ncnt);
  80. }
  81.  
  82. // check == 4 면 4방향 모두 막힌상태, 다음 코어로 넘어감
  83. if (check == 4) dfs(idx + 1, connect, cnt);
  84. }
  85. }
  86.  
  87. int main(void) {
  88. int T; cin >> T;
  89.  
  90. for (int t = 1; t <= T; t++) {
  91. cin >> n; core.clear();
  92. map = vector<vector<int>>(n, vector<int>(n));
  93.  
  94. for (int i = 0; i < n; i++)
  95. for (int j = 0; j < n; j++) {
  96. cin >> map[i][j];
  97. if (map[i][j] == CORE) {
  98. // 벽에 붙어있으면 wall의 값을 true로 저장
  99. if (i == 0 || j == 0 || i == n - 1 || j == n - 1) core.push_back(Core(i, j, true));
  100. else core.push_back(Core(i, j, false));
  101. }
  102. }
  103. ansWire = MAX;
  104. ansConnect = 0;
  105.  
  106. dfs(0, 0, 0);
  107. printf("#%d %d\n", t, ansWire);
  108. }
  109. }
Add Comment
Please, Sign In to add comment