zoukankan      html  css  js  c++  java
  • Technocup 2019

    http://codeforces.com/contest/1031

    (如果感觉一道题对于自己是有难度的,不要后退,懂0%的时候敲一遍,边敲边想,懂30%的时候敲一遍,边敲边想,懂60%的时候敲一遍,边敲边想,(真实情况是你其实根本不用敲那么多遍……),然后,这道题你就差不多可以拿下了ψ(`∇´)ψ)

    (IO模板在最后的蛋里)

    A. Golden Plate

    n*m矩形,最外圈为第一圈,间隔着选k个圈,问总共占多少给格子

    每圈贡献=2n‘+2m'-4,圈圈长宽以-4递减下去

    public static void main(String[] args) {
            IO io=new IO();
            int n=io.nextInt(),m=io.nextInt(),k=io.nextInt();
            long ans=0;
            while (k-->0){
                ans+=2*n+2*m-4;
                n-=4;m-=4;
            }
            io.println(ans);
        }
    

    B. Curiosity Has No Limits

    给你长度为n-1的两个数列,问是否存在长度为n的数列t,满足ai=ti|ti+1&&bi=ti&ti+1,三个数列的元素都属于[0,3]

    元素太少了,一开始想直接打表,但i、j到底哪个先哪个后不知道,所以从找规律入手

     1                 System.out.println(i+" "+j+" "+(i|j)+" "+(i&j));
     2 //对应ti、ti+1、ai、bi
     3 0 0 0 0
     4 0 1 1 0
     5 0 2 2 0
     6 0 3 3 0
     7 1 0 1 0
     8 1 1 1 1
     9 1 2 3 0
    10 1 3 3 1
    11 2 0 2 0
    12 2 1 3 0
    13 2 2 2 2
    14 2 3 3 2
    15 3 0 3 0
    16 3 1 3 1
    17 3 2 3 2
    18 3 3 3 3

    发现ti + ti+1==ai + bi,可以枚举t[0],看是否得到合法的数列t

     1  public static void main(String[] args) {
     2         IO io = new IO();
     3         int n = io.nextInt();
     4         int[] a = new int[n];
     5         int[] b = new int[n];
     6         int[] t = new int[n];
     7         for (int i = 0; i < n - 1; i++) a[i] = io.nextInt();
     8         for (int i = 0; i < n - 1; i++) b[i] = io.nextInt();
     9         OUT:
    10         for (int i = 0; i < 4; i++) {
    11             t[0] = i;
    12             for (int j = 1; j < n; j++) {
    13                 t[j] = a[j - 1] + b[j - 1] - t[j - 1];
    14                 if ((t[j] | t[j - 1]) != a[j - 1] ||
    15                         (t[j] & t[j - 1]) != b[j - 1]) continue OUT;
    16             }
    17             io.println("Yes");
    18             for (int j = 0; j < n; j++) io.print(t[j] + " ");
    19             return;
    20         }
    21         io.println("No");
    22     }

    C. Cram Time

    给你两个数a、b,输出元素总个数最多的且累加和分别不超过a、b的两组数,其中每个数只能用一次

    关键点在于当n是1+2+……+n<=a+b的最大的n时,1到n的所有数都一定选得上,只要对其中一个数从大到小取就可以保证

     1 public static void main(String[] args) {
     2         IO io = new IO();
     3         int a = io.nextInt(), b = io.nextInt(), cnt = 0, n = 0;
     4         long l = 1, r = a + b, mid;
     5         while (l <= r) {
     6             mid = (l + r) / 2;
     7             if (a + b < (mid + 1) * mid / 2) {
     8                 r = mid - 1;
     9             } else {
    10                 l = mid + 1;
    11                 n = (int) mid;
    12             }
    13         }
    14         int[] vis = new int[n + 1];
    15         for (int i = n; i >= 1; i--)
    16             if (a >= i) {
    17                 a -= i;
    18                 cnt++;
    19                 vis[i] = 1;
    20             }
    21         io.println(cnt);
    22         for (int i = 1; i <= n; i++) if (vis[i] == 1) io.print(i + " ");
    23         io.println("
    " + (n - cnt));
    24         for (int i = 1; i <= n; i++) if (vis[i] == 0) io.print(i + " ");
    25         io.close();
    26     }

    D. Minimum path

    有一个由小写字母填满的n*n矩阵,你可以改变不超过k个字母,使从(1,1)到(n,n)的字典序最小,你只能往右走或往下走

    k全部用来把前面非‘a'字符换成’a'。搜索从用完k后获得长度最长‘a'串开始。ans[i]表示答案的第i个字符,对于每个ans[i],搜索所有i可能的位置,取其最小值。因为对于每个特定的长度i,其末位置不会和长度i-1的末位置重叠(如下图),所以长度i得到的末尾点j,i-j+1,vis[j][i-j+1]表示为长度为i时该点是否可达。

    0 1 2 3 4 
    1 2 3 4 5 
    2 3 4 5 6 
    3 4 5 6 7 
    4 5 6 7 8 

     1  public static void main(String[] args) {
     2         IO io = new IO();
     3         int n = io.nextInt(), k = io.nextInt();
     4 
     5         int[][] a = new int[c][c];
     6         int[][] dp = new int[c][c];
     7         int[][] vis = new int[c][c];
     8         int[] ans = new int[c * 2];
     9 
    10         for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) a[i][j] = io.nextChar();
    11         int len = 0;
    12         //【初始化一定不要偷懒】
    13         vis[1][1] = 1;
    14         for (int i = 1; i <= n; i++)
    15             for (int j = 1; j <= n; j++) {
    16                 //【这里也是一样,不要贪图代码短】
    17                 if (i == 1 && j == 1) dp[1][1] = 0;
    18                 else if (i == 1) dp[1][j] = dp[1][j - 1];
    19                 else if (j == 1) dp[i][1] = dp[i - 1][1];
    20                 else dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]);
    21                 if (a[i][j] != 'a') dp[i][j]++;
    22                 if (dp[i][j] <= k) {
    23                     vis[i + 1][j] = vis[i][j + 1] = 1;
    24                     len = Math.max(i + j - 1, len);
    25                 }
    26             }
    27         Arrays.fill(ans, 'z');
    28         Arrays.fill(ans, 1, len + 1, 'a');
    29         for (int i = len + 1; i <= 2 * n - 1; i++) {
    30             for (int j = 1; j <= n; j++)
    31                 if (1 <= i - j + 1 && i - j + 1 <= n && vis[j][i - j + 1] == 1)
    32                     ans[i] = Math.min(ans[i], a[j][i - j + 1]);
    33             //因为最小点可能不止一个,所以不能只记录一个点
    34             for (int j = 1; j <= n; j++)
    35                 if (1 <= i - j + 1 && i - j + 1 <= n && vis[j][i - j + 1] == 1
    36                         && a[j][i - j + 1] == ans[i])
    37                     vis[j + 1][i - j + 1] = vis[j][i - j + 2] = 1;
    38         }
    39         for (int i = 1; i <= 2 * n - 1; i++) io.print((char) ans[i]);
    40     }

    E. Triple Flips

    给你长度为n的01串,你可以对其进行不超过n/3+12次操作将其变成全0串,该操作为选三个间隔相等的数将其翻转(0->1,1->0),如果存在解,请打印出所有操作数字的下标


    关键思想是每次保证最左边或最右边的三个数为0,字符串过小时枚举每一种情况。

      1     private static final int c = (int) (1e5 + 10);
      2     static IO io = new IO();
      3     static int n;
      4     static int[] a = new int[c];
      5     //一边操作一边记录
      6     static ArrayList<int[]> ans = new ArrayList<>();
      7 
      8     static void solve0(int l, int r) {
      9         ArrayList<int[]> p = new ArrayList<>();
     10         int[] t = new int[c];
     11         int a1, a2;
     12 
     13         for (int i = l; i <= r; i++) for (int j = i + 2; j <= r; j += 2) p.add(new int[]{i, j});
     14         OUT:
     15         for (int i = 0; i < 1 << p.size(); i++) {
     16             System.arraycopy(a, l, t, l, r - l + 1);
     17             for (int j = 0; j < p.size(); j++)
     18                 if ((i >> j & 1) == 1) {
     19                     a1 = p.get(j)[0];
     20                     a2 = p.get(j)[1];
     21                     t[a1] ^= 1;
     22                     t[a2] ^= 1;
     23                     t[a1 + a2 >> 1] ^= 1;
     24                 }
     25             for (int j = l; j <= r; j++) if (t[j] == 1) continue OUT;
     26             for (int j = 0; j < p.size(); j++)
     27                 if ((i >> j & 1) == 1) ans.add(p.get(j));
     28 
     29             io.println("YES");
     30             io.println(ans.size());
     31             for (int[] v : ans) io.println(v[0] + " " + (v[0] + v[1] >> 1) + " " + v[1]);
     32             return;
     33         }
     34         io.println("NO");
     35     }
     36 
     37     //坚定不移保证左三或右三全为0
     38     static void solve(int l, int r) {
     39         //flip需要长度至少为7
     40         if (r - l + 1 < 7) {
     41             while (l > 1 && r - l + 1 < 8) l--;
     42             while (r < n && r - l + 1 < 8) r++;
     43             solve0(l, r);
     44             return;
     45         }
     46         if (a[l] == 0) {
     47             solve(l + 1, r);
     48             return;
     49         }
     50         if (a[r] == 0) {
     51             solve(l, r - 1);
     52             return;
     53         }
     54         //111……
     55         if (a[l + 1] == 1 && a[l + 2] == 1) {
     56             flip_add(l, l + 2);
     57             solve(l + 3, r);
     58             return;
     59         }
     60         //……111
     61         if (a[r - 1] == 1 && a[r - 2] == 1) {
     62             flip_add(r - 2, r);
     63             solve(l, r - 3);
     64             return;
     65         }
     66         //101……
     67         if (a[l] == 1 && a[l + 2] == 1) {
     68             flip_add(l, l + 4);
     69             solve(l + 3, r);
     70             return;
     71         }
     72         //……101
     73         if (a[r - 2] == 1 && a[r] == 1) {
     74             flip_add(r - 4, r);
     75             solve(l, r - 3);
     76             return;
     77         }
     78         //100……翻转分别为l、l+2、l+4,目标是结果为000
     79         if (a[l + 1] == 0 && a[l + 2] == 0) {
     80             flip_add(l, l + 6);
     81             solve(l + 3, r);
     82             return;
     83         }
     84         //……001
     85         if (a[r - 1] == 0 && a[r - 2] == 0) {
     86             flip_add(r - 6, r);
     87             solve(l, r - 3);
     88             return;
     89         }
     90         //110……和……011
     91         if ((r - l + 1) % 2 == 1) {
     92             flip_add(l, r);
     93             flip_add(l + 1, r - 1);
     94             solve(l + 3, r - 3);
     95         } else {
     96             flip_add(l, r - 1);
     97             flip_add(l + 1, r);
     98             solve(l + 3, r - 3);
     99         }
    100     }
    101 
    102     public static void main(String[] args) {
    103         n = io.nextInt();
    104         for (int i = 1; i <= n; i++) a[i] = io.nextInt();
    105         solve(1, n);
    106     }111     
    112     //0变1,1变0
    113     static void flip_add(int l, int r) {
    114         a[l] ^= 1;
    115         a[r] ^= 1;
    116         a[l + r >> 1] ^= 1;
    117         ans.add(new int[]{l, r});
    118     }

    F. Familiar Operations

    有正整数a、b以及两种操作:1、对其中一个数乘以某个素数,2、对其中一个数除以其素因子,问让两个数因子数相同的最小操作是多少。

     1     public static void main(String[] args) {
     2         int[] prim = new int[c];
     3         int[][][] dp = new int[289][31][1201];
     4         HashSet<ArrayList<Integer>> s = new HashSet<>();
     5         ArrayList<Integer> t = new ArrayList<>();
     6         ArrayList<ArrayList<Integer>> qt = new ArrayList<>();
     7         ArrayList<Integer>[] v = new ArrayList[c];
     8         for (int i = 1; i < c; i++) v[i] = new ArrayList<>(7);
     9         Arrays.fill(prim, 1);
    10 
    11         for (int i = 2; i < c; i++)
    12             if (prim[i] == 1) for (int j = 1; i * j < c; j++) {
    13                 int x = j;
    14                 int p = 2;
    15                 while (x % i == 0) {
    16                     x /= i;
    17                     p++;
    18                 }
    19                 v[i * j].add(p);
    20                 prim[i * j] = 0;
    21             }
    22         for (int i = 1; i < c; i++) while (v[i].size() < 7) v[i].add(1);
    23         for (int i = 1; i < c; i++) {
    24             Collections.sort(v[i]);
    25             s.add(v[i]);
    26         }
    27         qt.addAll(s);
    28         for (int i = 0; i < qt.size(); i++)
    29             for (int j = 0; j <= 30; j++) Arrays.fill(dp[i][j], 999);
    30         for (int y = 0; y < qt.size(); y++) {
    31             t.clear();
    32             for (int i = 0; i < 7; i++) t.add(qt.get(y).get(i));
    33             while (t.size() < 30) t.add(1);
    34             dp[y][0][1] = 0;
    35             for (int i = 0; i < 30; i++) {
    36                 for (int j = 1; j <= 1200; j++) {
    37                     if (dp[y][i][j] < 999) for (int l = 1; j * l <= 1200; l++)
    38                         dp[y][i + 1][j * l] = Math.min(dp[y][i + 1][j * l],
    39                                 dp[y][i][j] + Math.abs(t.get(i) - l));
    40                 }
    41             }
    42         }
    43 
    44         IO io = new IO();
    45         int n = io.nextInt();
    46         while (n-- > 0) {
    47             int p1 = qt.indexOf(v[io.nextInt()]), g1 = qt.indexOf(v[io.nextInt()]);
    48             int ans = 9000;
    49             for (int j = 1; j <= 1200; j++) ans = Math.min(ans, dp[p1][30][j] + dp[g1][30][j]);
    50             io.println(ans);
    51         }
    52     }

    彩蛋(/≧▽≦)/丢~快接~

    View Code
  • 相关阅读:
    asp.net中合并DataGrid行
    将Asp.Net页面输出到EXCEL里去····
    清空Sql数据库日志等操作
    opengl 教程(14) 摄像机控制(1)
    awk使用技巧
    opengl 教程(10) index draw
    opengl 教程(12) 投影矩阵
    opengl 教程(9) 顶点属性插值
    opengl 教程(15) 摄像机控制(2)
    opengl 教程(11) 平移/旋转/缩放
  • 原文地址:https://www.cnblogs.com/towerbird/p/9933746.html
Copyright © 2011-2022 走看看