Advertisement
qwerty787788

Furniture task

May 24th, 2013
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.47 KB | None | 0 0
  1. import java.io.*;
  2. import java.util.*;
  3.  
  4. public class furniture {
  5.     FastScanner in;
  6.     PrintWriter out;
  7.  
  8.     class Job implements Comparable<Job> {
  9.         int deadline, id;
  10.  
  11.         public Job(int deadline, int id) {
  12.             super();
  13.             this.deadline = deadline;
  14.             this.id = id;
  15.         }
  16.  
  17.         @Override
  18.         public int compareTo(Job o) {
  19.             return Integer.compare(deadline, o.deadline);
  20.         }
  21.  
  22.     }
  23.  
  24.     int[][] color;
  25.     HashMap<Integer, Integer>[] usedColorsInRows;
  26.     HashMap<Integer, Integer>[] usedColorsInColumns;
  27.  
  28.     void conflictColumn(int x, int y, int newColor, int nextColor) {
  29.         usedColorsInColumns[y].remove(color[x][y]);
  30.         color[x][y] = newColor;
  31.         usedColorsInRows[x].put(newColor, y);
  32.         int failX = -1;
  33.         if (usedColorsInColumns[y].containsKey(newColor)) {
  34.             failX = usedColorsInColumns[y].get(newColor);
  35.         }
  36.         usedColorsInColumns[y].put(newColor, x);
  37.         if (failX != -1) {
  38.             conflictRow(failX, y, nextColor, newColor);
  39.         }
  40.     }
  41.  
  42.     void conflictRow(int x, int y, int newColor, int nextColor) {
  43.         usedColorsInRows[x].remove(color[x][y]);
  44.         color[x][y] = newColor;
  45.         usedColorsInColumns[y].put(newColor, x);
  46.         int failY = -1;
  47.         if (usedColorsInRows[x].containsKey(newColor)) {
  48.             failY = usedColorsInRows[x].get(newColor);
  49.         }
  50.         usedColorsInRows[x].put(newColor, y);
  51.         if (failY != -1) {
  52.             conflictColumn(x, failY, nextColor, newColor);
  53.         }
  54.     }
  55.  
  56.     boolean check(int[][] a) {
  57.         for (int i = 0; i < a.length; i++) {
  58.             HashSet<Integer> hs = new HashSet<>();
  59.             for (int j = 0; j < a[i].length; j++) {
  60.                 int val = a[i][j];
  61.                 if (hs.contains(val))
  62.                     return false;
  63.                 hs.add(val);
  64.             }
  65.         }
  66.         for (int j = 0; j < a[0].length; j++) {
  67.             HashSet<Integer> hs = new HashSet<>();
  68.             for (int i = 0; i < a.length; i++) {
  69.                 int val = a[i][j];
  70.                 if (hs.contains(val))
  71.                     return false;
  72.                 hs.add(val);
  73.             }
  74.         }
  75.         return true;
  76.     }
  77.  
  78.     void solve2(int n, int m, int v, int[] aa) {
  79.         Job[] a = new Job[n];
  80.         int maxDeadline = 0;
  81.         for (int i = 0; i < n; i++) {
  82.             a[i] = new Job(aa[i], i);
  83.             maxDeadline = Math.max(maxDeadline, a[i].deadline);
  84.         }
  85.         maxDeadline++;
  86.         Arrays.sort(a);
  87.         int l = -1, r = n;
  88.         while (r - l > 1) {
  89.             int med = (l + r) / 2;
  90.             if (a[med].deadline < m) {
  91.                 l = med;
  92.                 continue;
  93.             }
  94.             int[] cnt = new int[maxDeadline];
  95.             for (int i = med; i < n; i++) {
  96.                 for (int j = a[i].deadline - m + 1; j <= a[i].deadline; j++)
  97.                     cnt[j]++;
  98.             }
  99.             while (true) {
  100.                 int lastOk = 1;
  101.                 int fail = -1;
  102.                 for (int i = 2; i < maxDeadline; i++) {
  103.                     if (cnt[i] < m) {
  104.                         lastOk = i;
  105.                     } else {
  106.                         if (cnt[i] > m) {
  107.                             fail = i;
  108.                             break;
  109.                         }
  110.                     }
  111.                 }
  112.                 if (fail == -1)
  113.                     break;
  114.                 cnt[lastOk]++;
  115.                 cnt[fail]--;
  116.             }
  117.             if (cnt[1] <= m) {
  118.                 r = med;
  119.             } else {
  120.                 l = med;
  121.             }
  122.         }
  123.         out.println(r * v);
  124.         ArrayList<Integer>[] g = new ArrayList[maxDeadline];
  125.         for (int i = 0; i < g.length; i++)
  126.             g[i] = new ArrayList<>();
  127.         for (int i = r; i < n; i++) {
  128.             for (int j = a[i].deadline - m + 1; j <= a[i].deadline; j++) {
  129.                 g[j].add(i);
  130.             }
  131.         }
  132.         HashSet<Integer> hs = new HashSet<>();
  133.         while (true) {
  134.             int lastOk = 1;
  135.             int fail = -1;
  136.             for (int i = 2; i < maxDeadline; i++) {
  137.                 if (g[i].size() < m) {
  138.                     lastOk = i;
  139.                 } else {
  140.                     if (g[i].size() > m) {
  141.                         fail = i;
  142.                         break;
  143.                     }
  144.                 }
  145.             }
  146.             if (fail == -1)
  147.                 break;
  148.             hs.clear();
  149.             for (int i : g[lastOk]) {
  150.                 hs.add(i);
  151.             }
  152.             for (int i = g[fail].size() - 1; i >= 0; i--) {
  153.                 if (!hs.contains(g[fail].get(i))) {
  154.                     int xx = g[fail].get(i);
  155.                     g[fail].remove(i);
  156.                     g[lastOk].add(xx);
  157.                     break;
  158.                 }
  159.             }
  160.         }
  161.  
  162.         int can = n - r;
  163.         boolean[][] gg = new boolean[can][maxDeadline];
  164.         for (int day = 0; day < maxDeadline; day++) {
  165.             for (int x : g[day]) {
  166.                 gg[x - r][day] = true;
  167.             }
  168.         }
  169.         color = new int[can][maxDeadline];
  170.         for (int i = 0; i < color.length; i++)
  171.             Arrays.fill(color[i], -1);
  172.         usedColorsInRows = new HashMap[can];
  173.         for (int i = 0; i < can; i++)
  174.             usedColorsInRows[i] = new HashMap<>();
  175.         usedColorsInColumns = new HashMap[maxDeadline];
  176.         for (int i = 0; i < maxDeadline; i++)
  177.             usedColorsInColumns[i] = new HashMap<>();
  178.         for (int i = 0; i < can; i++)
  179.             for (int j = 0; j < maxDeadline; j++)
  180.                 if (gg[i][j]) {
  181.                     for (int newColor = 0; newColor < m; newColor++) {
  182.                         if (!usedColorsInColumns[j].containsKey(newColor)) {
  183.                             color[i][j] = newColor;
  184.                             usedColorsInColumns[j].put(newColor, i);
  185.                             int failY = -1;
  186.                             if (usedColorsInRows[i].containsKey(newColor)) {
  187.                                 failY = usedColorsInRows[i].get(newColor);
  188.                             }
  189.                             usedColorsInRows[i].put(newColor, j);
  190.                             if (failY != -1) {
  191.                                 for (int newColor2 = 0; newColor2 < m; newColor2++) {
  192.                                     if (!usedColorsInRows[i]
  193.                                             .containsKey(newColor2)) {
  194.                                         conflictColumn(i, failY, newColor2,
  195.                                                 newColor);
  196.                                         break;
  197.                                     }
  198.                                 }
  199.                             }
  200.                             break;
  201.                         }
  202.                     }
  203.                 }
  204.         int[][] ans = new int[n][m];
  205.         for (int i = 0; i < can; i++)
  206.             for (int j = 0; j < maxDeadline; j++)
  207.                 if (color[i][j] != -1)
  208.                     ans[a[i + r].id][color[i][j]] = j;
  209.         int SOME_CONST = 10000;
  210.         for (int st = 0; st < r; st += m) {
  211.             int cnt = Math.min(r, st + m) - st;
  212.             for (int i = 0; i < cnt; i++)
  213.                 for (int job = 0; job < m; job++)
  214.                     ans[a[st + i].id][job] = SOME_CONST + st + ((i + job) % m);
  215.         }
  216.         if (!check(ans))
  217.             throw new AssertionError();
  218.         for (int i = 0; i < n; i++) {
  219.             for (int j = 0; j < m; j++)
  220.                 out.print(ans[i][j] + " ");
  221.             out.println();
  222.         }
  223.  
  224.     }
  225.  
  226.     Random rnd = new Random(123);
  227.  
  228.     void solve() {
  229.         int n = in.nextInt();
  230.         int m = in.nextInt();
  231.         int v = in.nextInt();
  232.         int[] dead = new int[n];
  233.         for (int i = 0; i < n; i++)
  234.             dead[i] = in.nextInt();
  235.         solve2(n, m, v, dead);
  236.          
  237.  
  238.         /*
  239.         for (int test = 0;; test++) {
  240.             long st = System.currentTimeMillis();
  241.             System.err.println(test);
  242.             int n = 200;
  243.             int m = 100;
  244.             int[] a = new int[n];
  245.             for (int i = 0; i < n; i++) {
  246.                 a[i] = rnd.nextInt(1000) + 100;
  247.             }
  248.             solve2(n, m, 100, a);
  249.             System.err.println(System.currentTimeMillis() - st);
  250.         }
  251.         */
  252.  
  253.     }
  254.  
  255.     void run() {
  256.         try {
  257.             in = new FastScanner(new File("fur*iture.in"));
  258.             out = new PrintWriter(new File("f*rniture.out"));
  259.  
  260.             solve();
  261.  
  262.             out.close();
  263.         } catch (FileNotFoundException e) {
  264.             e.printStackTrace();
  265.         }
  266.     }
  267.  
  268.     void runIO() {
  269.  
  270.         in = new FastScanner(System.in);
  271.         out = new PrintWriter(System.out);
  272.  
  273.         solve();
  274.  
  275.         out.close();
  276.     }
  277.  
  278.     class FastScanner {
  279.         BufferedReader br;
  280.         StringTokenizer st;
  281.  
  282.         public FastScanner(File f) {
  283.             try {
  284.                 br = new BufferedReader(new FileReader(f));
  285.             } catch (FileNotFoundException e) {
  286.                 e.printStackTrace();
  287.             }
  288.         }
  289.  
  290.         public FastScanner(InputStream f) {
  291.             br = new BufferedReader(new InputStreamReader(f));
  292.         }
  293.  
  294.         String next() {
  295.             while (st == null || !st.hasMoreTokens()) {
  296.                 String s = null;
  297.                 try {
  298.                     s = br.readLine();
  299.                 } catch (IOException e) {
  300.                     e.printStackTrace();
  301.                 }
  302.                 if (s == null)
  303.                     return null;
  304.                 st = new StringTokenizer(s);
  305.             }
  306.             return st.nextToken();
  307.         }
  308.  
  309.         boolean hasMoreTokens() {
  310.             while (st == null || !st.hasMoreTokens()) {
  311.                 String s = null;
  312.                 try {
  313.                     s = br.readLine();
  314.                 } catch (IOException e) {
  315.                     e.printStackTrace();
  316.                 }
  317.                 if (s == null)
  318.                     return false;
  319.                 st = new StringTokenizer(s);
  320.             }
  321.             return true;
  322.         }
  323.  
  324.         int nextInt() {
  325.             return Integer.parseInt(next());
  326.         }
  327.  
  328.         long nextLong() {
  329.             return Long.parseLong(next());
  330.         }
  331.     }
  332.  
  333.     public static void main(String[] args) {
  334.         new furniture().run();
  335.     }
  336. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement