法師サメとバーバラ-白駿(21610、シミュレーション)


🎯 魔女サメと琵琶魚


魔女サメと琵琶魚-21160、シミュレーション、金貨5

🧐 アルゴリズム[メソッド]


  • ストレージクラウドの場所を宣言する配列

  • 周囲(←,↖,↑,↔,→,‐,↓,͜)移動の配列宣言,奇数時対角線移動

  • クラウド移動関数の実装(領域を超えた場合に初めて移動)

  • インクリメンタル関数の実装

  • レプリケーション水の関数の実装

  • クラウドを除去した後にクラウドを生成する関数を実現

  • ゾーン全体のカウント関数の実装
  • 👨‍💻 ソース

    import java.util.*;
    
    public class Main {
        static class Node {
            int x;
            int y;
            
            Node(int x, int y) {
                this.x = x;
                this.y = y;
            }
        }
        
        static int N; // 격자 크기
        static int M; // 이동 횟수
        
        static int[][] map;
        
        static ArrayList<Node> cloudList = new ArrayList<Node>();
        
        // ←, ↖, ↑, ↗, →, ↘, ↓, ↙
        static final int dx[] = {0 , -1, -1, -1, 0, 1, 1,  1};
        static final int dy[] = {-1, -1,  0,  1, 1, 1, 0, -1};
        
        public static void main(String[] args)
        {
            Scanner sc = new Scanner(System.in);
            
            N = sc.nextInt();
            M = sc.nextInt();
            sc.nextLine();
            
            map = new int[N + 1][N + 1];
            for(int i = 1 ; i <= N ; i++) {
                for(int j = 1 ; j <= N ; j++) {
                    map[i][j] = sc.nextInt();
                }
            }
            
            InitCloud();  // 구름 초기 설정
            
            for(int i = 0 ; i < M ; i++) {
                int d = sc.nextInt(); // 이동 방향
                int s = sc.nextInt(); // 이동 칸수
                sc.nextLine();
                
                moveCloud(d, s);	// 구름 이동
                
                increaseWater();	// 물 증가
                
                copyWater();		// 물 복사
                
                createCloud();		// 구름 생성
            }
            
            System.out.println(countWater());
            
            sc.close();
        }
        
        static int countWater() { // 물 개수 카운트
            int count = 0;
            
            for(int i = 1 ; i <= N ; i++) {
              for(int j = 1 ; j <= N ; j++) {
                  count += map[i][j];
              }
            }
            
            return count;
        }
        
        static void createCloud() { // 구름 생성
            ArrayList<Node> tempCloudList = new ArrayList<Node>();
            
            for(int i = 1 ; i <= N ; i++) {
                for(int j = 1 ; j <= N ; j++) {
                    if(2 <= map[i][j]) {
                        
                        boolean flag = true;
                        for(int k = 0 ; k < cloudList.size() ; k++) {
                          Node n = cloudList.get(k);
                          
                          int x = n.x;
                          int y = n.y;
                          
                          if(x == i && y == j) {
                            flag = false;
                            break;
                          }
                        }
                        
                        if(flag) {
                          map[i][j] -= 2;
                          tempCloudList.add(new Node(i, j));
                        }
                        
                    }
                }
            }
            
            removeCloud();
            cloudList = tempCloudList;
        }
        
        static void copyWater() { // 물 복사 마법 실행
            for(int i = 0 ; i < cloudList.size() ; i++) {
                Node n = cloudList.get(i);
                
                int x = n.x;
                int y = n.y;
                
                int count = 0;
                for(int d = 1 ; d < dx.length ; d += 2) {
                    int nx = x + dx[d];
                    int ny = y + dy[d];
                   
                    if(1 <= nx && nx <= N && 1 <= ny && ny <= N) {
                        if(0 != map[nx][ny]) {
                            count++;
                        }
                    }
                }
                
                map[x][y] += count;
            }
        }
        
        static void removeCloud() {   // 구름 제거
            cloudList = new ArrayList<Node>();
        }
        
        static void increaseWater() { // 구름이 있는 칸은 비가 내려 1씩 증가
          for(int i = 0 ; i < cloudList.size() ; i++) {
              Node n = cloudList.get(i);
              
              int x = n.x;
              int y = n.y;
              
              map[x][y] += 1;
          }
        }
        
        static void moveCloud(int direction, int moveCount) {   // 구름 이동
            for(int i = 0 ; i < cloudList.size() ; i++) {
                Node n = cloudList.get(i);
              
                int x = n.x;
                int y = n.y;
              
                int nx = x + (dx[direction - 1] * moveCount);
                int ny = y + (dy[direction - 1] * moveCount);
    
                n = correctionCloud(new Node(nx, ny));
                
                cloudList.set(i, n);
            }
        }
        
        static Node correctionCloud(Node node) {  // 이동 후 구름이 map 범위를 벗어났을 때 구름 위치 교정
            int x = node.x;
            int y = node.y;
          
            while(!(1 <= x && x <= N)) {
                if(1 > x) {
                    x += N;
                } else if(N < x){
                    x -= N;
                }
            }
            
            while(!(1 <= y && y <= N)) {
                if(1 > y) {
                    y += N;
                } else if(N < y){
                    y -= N;
                }
            }
    
            return new Node(x, y);
        }
        
        static void InitCloud() { // 구름 초기 설정
            cloudList.add(new Node(N, 1));
            cloudList.add(new Node(N, 2));
            cloudList.add(new Node(N - 1, 1));
            cloudList.add(new Node(N - 1, 2));
        }
        
    }

    🏅 結果



    🗨ポスト

  • 題タイプは模擬問題なので順番に実施すれば良いので、簡単ですが時間がかかりました.
  • で実現すべき機能をすべて関数化し,エラーが発生した場合に容易に修正できる.
  • 📖 関連知識