【At Coder begin 345】[D - Tiling] 回溯

题目链接:<problem D>

解法:

  1. 比较简单。看代码。

    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.StreamTokenizer;
    import java.util.Set;
    import java.util.TreeSet;

    public class Main {
    static int n, h, w;
    static int[][] ties;

     static boolean[][] writed ;
    
     static boolean[] used;
    
     static boolean over = false;
    
     static Set<Integer> set = new TreeSet<>();
     public static void main(String[] args) throws IOException {
         StreamTokenizer st = new StreamTokenizer(new InputStreamReader(System.in));
         st.nextToken();
         n = (int) st.nval;
         st.nextToken();
         h = (int) st.nval;
         st.nextToken();
         w = (int) st.nval;
    
         ties = new int[n][2];
         for (int i = 0; i < n; i++) {
             st.nextToken();
             int a = (int) st.nval;
             st.nextToken();
             int b = (int) st.nval;
             ties[i][0] = a;
             ties[i][1] = b;
         }
         writed = new boolean[h][w];
         used = new boolean[n];
         for(int i=0;i<h;i++){
             for(int j=0;j<w;j++){
                 set.add(i*w+j);
             }
         }
         dfs(0,0,0);
         System.out.println(over?"Yes":"No");
     }
    
     public static boolean canplace(int i,int topx,int topy,int dir){
         int r = ties[i][dir];
         int c = ties[i][1-dir];
         for(int x=topx;x<topx+r;x++){
             if( x<0 || x >=h) {
                 return false;
             }
             for(int y=topy;y<topy+c;y++){
                 if( y<0 || y>=w) {
                     return false;
                 }
                 if(writed[x][y]) {
                     return false;
                 }
             }
         }
         return true;
     }
    
     public static void place(int i,int topx,int topy,int dir){
         int r = ties[i][dir];
         int c = ties[i][1-dir];
         for(int x=topx;x<topx+r;x++){
             for(int y=topy;y<topy+c;y++){
                writed[x][y] = true;
                set.remove(x*w + y);
             }
         }
         used[i] = true;
     }
    
     public static  boolean check() {
         if( set.isEmpty()) {
             return true;
         }
         return false;
     }
    
     public static void replace(int i,int topx,int topy,int dir) {
         int r = ties[i][dir];
         int c = ties[i][1-dir];
         for(int x=topx;x<topx+r;x++){
             for(int y=topy;y<topy+c;y++){
                 writed[x][y] = false;
                 set.add(x*w + y);
             }
         }
         used[i] = false;
     }
    
     public static void dfs(int depth,int topx,int topy) {
         if(over) {
             return;
         }
    
         if( check()){
             over = true;
             return;
         }
    
         for(int i=0;i<n;i++){
             for(int dir=0;dir<=1;dir++) {
                 if (!used[i] && canplace(i, topx, topy, dir)) {
                     place(i, topx, topy, dir);
                     if(check()){
                         over = true;
                         return;
                     }
                     int[] next = update();
                     dfs(depth + 1, next[0],next[1]);
                     replace(i, topx, topy, dir);
                 }
             }
         }
     }
    
     public static int[] update() {
         int u = set.stream().findFirst().orElse(0);
         return new int[]{u/w,u%w};
     }
    

    }