白駿16234人口移転(Java)


リンク


質問リンク

問題の説明


N×Nサイズの地があり、地は1×格子に分ける.どの土地にも一つの国があり、r行c列の国にはA[r][c]名が住んでいる.隣国の間に境界線がある.すべての国×1サイズなので、すべての境界は正方形です.
今日から人口移転の日です.
人口移転は1日以内に以下の方法で行われ、以下の方法で人口移転が行われなくなるまで行われる.
  • 国境線を共有する両国の人口差がL名以上、R名以下であれば、両国が共有する国境線は今日開かれる.
  • 位の条件に従ってすべての境界線を開くと、人口の流れが開始される.
  • 国境線が開いていて、隣の1つの格子でしか移動できないなら、今日の1日でこの国は連合と呼ばれています.
  • 連合体を構成する各間の人口数は(連合体の人口数)/(連合体の個数)である.便利な小数点を捨てる.
  • 連盟を解散し、すべての国境線を閉鎖した.
  • 国ごとの人口数が与えられると、人口の流れが数日以内に発生する状況を知るプログラムを作成してください.

    入力


    1行目はN,L,Rである.(1 ≤ N ≤ 50, 1 ≤ L ≤ R ≤ 100)
    2列目から、国ごとの人口数がN行に割り当てられます.r行c列に与えられる整数は、A[r][c]の値である.(0 ≤ A[r][c] ≤ 100)
    人口移転が発生した日数が2000回未満の入力のみを与えます.

    しゅつりょく


    人口の流れは数日発生し,1行目に並んだ.

    I/O例...白俊も説明した。


    ここを参照

    に答える

  • n Dayがすべきこと
    1-1. 結合できるすべての要素が縛られています.
    1-2. 要素を計算し、翌日までに値を変更します.
  • 1号の作業を、国が連合できないまで繰り返します.
  • 2重砲口をwhileドアの中に置くのは少し反感がありますか?と言うべきなのですが、ちょっと危険なようで、その方法を避けるために約30分も時間を浪費して、この方法でコードを書いて、それから通過しました!
    注意すべき点は、翌日になると、アクセスまたは統合配列を初期化する必要があります.

    コード#コード#

    package Sample;
    
    import java.util.*;
    class Point {
    	int x, y;
    	Point(int x, int y) {
    		this.x = x;
    		this.y = y;
    	}
    }
    public class Main {
    	static int[][] map;
    	static boolean[][] visited;
    	static int[] dx = { -1, 0, 1, 0 };
    	static int[] dy = { 0, 1, 0, -1 };
    	static ArrayList<ArrayList<Point>> all = new ArrayList<>();
    	public static ArrayList<Point> bfs(int sx, int sy, int N, int L, int R) {
    		Queue<Point> q = new LinkedList<>();
    		ArrayList<Point> union= new ArrayList<>();
    		
    		q.add(new Point(sx,sy));
    		union.add(new Point(sx,sy));
    
    		visited[sx][sy] = true;
    		while(!q.isEmpty()) {
    			Point p = q.poll();
    			
    			for(int i = 0; i < 4; i++) {
    				int nx = p.x + dx[i];
    				int ny = p.y + dy[i];
    				
    				if(nx < 0 || nx >= N || ny < 0 || ny >= N)
    					continue;
    				int move = Math.abs(map[p.x][p.y]- map[nx][ny]);
    				if(!visited[nx][ny] && move >= L && move <= R) {
    					visited[nx][ny] = true;
    					Point np = new Point(nx, ny);
    					q.add(np);
    					union.add(np);
    				}
    			}
    		}
    		return union;
    	}
    	public static void main(String[] args) {
    		Scanner sc = new Scanner(System.in);
    		int N = sc.nextInt();
    		int L = sc.nextInt();
    		int R = sc.nextInt();
    		map = new int[N][N];
    		for(int i = 0; i < N; i++)
    			for(int j = 0; j < N; j++)
    				map[i][j] = sc.nextInt();
    		int answer = 0;
    		ArrayList<Point> union;
    		while(true) {
    			all.clear();
    			visited = new boolean[N][N];
    			for(int i = 0; i < N; i++) {
    				for(int j = 0; j < N; j++) {
    					if(!visited[i][j]) {
    						union = bfs(i,j,N,L,R);
    						if(union.size() > 1) {
    							all.add(union);
    						}
    					}
    				}
    			}
    			for(int i = 0; i < all.size(); i++) {
    				int sum = 0;
    				for(int j = 0; j < all.get(i).size(); j++)
    				{
    					sum += map[all.get(i).get(j).x][all.get(i).get(j).y];
    				}
    				for(int j = 0; j < all.get(i).size(); j++)
    				{
    					map[all.get(i).get(j).x][all.get(i).get(j).y] = sum / all.get(i).size();
    				}
    			}
    			if(all.size() == 0) break;
    			answer++;
    		}
    		System.out.println(answer);
    	}
    }