zoukankan      html  css  js  c++  java
  • TZOJ 挑战题库随机训练10(JAVA)

    点击题号跳转

    A5985 B1792 C5644 D4038 E3229

    F3322 G3614 H2824 I4286 J6225

    A.矩形嵌套回到顶部

    题意

    n个矩形嵌套,跟E题类似,求最多嵌套,n<=1000

    题解

    这个题因为比较的是点对,所以可以先排序,使得第一维有序,然后只需要求出第二维的最长上升子序列,复杂度O(nlogn)

    代码

     1 import java.util.*;
     2 
     3 public class Main {
     4 
     5     public static void main(String[] args) {
     6 
     7         Solution solver = new Solution();
     8         solver.solve();
     9     }
    10 
    11 }
    12 
    13 class Solution {
    14 
    15     private final int N = 1005;
    16 
    17     private int[] dp = new int[N << 1];
    18     private List<Node> list = new ArrayList<>();
    19 
    20     class Node {
    21         int l, r;
    22         Node(int l, int r) {
    23             this.l = l;
    24             this.r = r;
    25         }
    26     }
    27 
    28     public void solve() {
    29         Scanner sc = new Scanner(System.in);
    30         int t = sc.nextInt();
    31         while (sc.hasNext()) {
    32             int n = sc.nextInt();
    33             list.clear();
    34             for (int i = 0; i < n; i++) {
    35                 int l = sc.nextInt();
    36                 int r = sc.nextInt();
    37                 list.add(new Node(l, r));
    38                 list.add(new Node(r, l));
    39                 dp[i] = dp[n + i] = 0;
    40             }
    41 
    42             Collections.sort(list, (o1, o2) -> {
    43                 if (o1.l > o2.l) return 1;
    44                 else if (o1.l == o2.l) {
    45                     if (o1.r > o2.r) return 1;
    46                     else if (o1.r == o2.r) return 0;
    47                 }
    48                 return -1;
    49             });
    50 
    51             //list.stream().forEach((node) -> System.out.println(node.l + " " + node.r));
    52 
    53             int maxx = 0;
    54             for (int i = 0; i < n << 1; i++) {
    55                 dp[i] = 1;
    56                 for (int j = 0; j < i; j++) {
    57                     if (list.get(i).l > list.get(j).l && list.get(i).r > list.get(j).r) {
    58                         dp[i] = Math.max(dp[i], dp[j] + 1);
    59                     }
    60                 }
    61                 maxx = Math.max(maxx, dp[i]);
    62             }
    63 
    64             System.out.println(maxx);
    65         }
    66     }
    67 }
    A

    B.Introspective Caching回到顶部

    题意

    背景:类似于操作系统的请求分页(分段)过程

    快速缓冲区大小c,n个不同的程序,q次请求访问快速缓冲区的程序,问最少需要多少次把程序调入快速缓冲区,q<=10^5

    题解

    这样想,需要删除的元素肯定是要最远(值r)才有用的,如果删的不是最远的(值v),那么就会在r之前把v再调入快速缓冲区,如果删了最远的,这次操作就可以省略

    每个程序维护一个nxt[i],nxt[i]代表值为i的下一个位置,用TreeSet维护,复杂度O(nlogn)

    PS:TreeSet自定义类需要实现Comparable,然后重载compareTo方法,TreeSet底层红黑树,会自动排序,排序会调用compareTo方法

    PS:TreeSet.contains会调用compareTo方法用0来判断相同

    PS:compareTo值为正表示A>B,值为0表示A=B,值为负表示A<B

    PS:一开始contains方法没起作用调了好久,后来发现判断相同需要返回0,因为自动排序正交换0和负不交换,就忽略了0的处理

    代码

     1 import java.util.*;
     2 
     3 public class Main {
     4 
     5     public static void main(String[] args) {
     6         Solution solver = new Solution();
     7         solver.solve();
     8     }
     9 
    10 }
    11 
    12 class Solution {
    13 
    14     class Node implements Comparable<Node> {
    15 
    16         int i, val;
    17 
    18         Node(int i, int val) {
    19             this.i = i;
    20             this.val = val;
    21         }
    22 
    23         //@Override
    24         public int compareTo(Node o) {
    25             if (i < o.i) return 1;
    26             else if (i > o.i) return -1;
    27             else return 0;
    28         }
    29     }
    30 
    31     public void solve() {
    32         Scanner sc = new Scanner(System.in);
    33         int c = sc.nextInt();
    34         int n = sc.nextInt();
    35         int q = sc.nextInt();
    36         int[] a = new int[q + 5];
    37         int[] nxt = new int[q + 5];
    38         int[] ha = new int[n + 5];
    39         for (int i = 1; i <= q; i++) a[i] = sc.nextInt();
    40         for (int i = q; i >= 1; i--) {
    41             if (ha[a[i]] == 0) nxt[i] = q + 1;
    42             else nxt[i] = ha[a[i]];
    43             ha[a[i]] = i;
    44         }
    45         TreeSet<Node> treeSet = new TreeSet<>();
    46 //        Node node1 = new Node(1, 2);
    47 //        treeSet.add(node1);
    48 //        treeSet.add(new Node(2, 3));
    49 //        treeSet.add(new Node(1, 3));
    50 //        treeSet.add(new Node(5, 7));
    51 //        treeSet.stream().forEach((node) -> System.out.println(node.i + " " + node.val));
    52 //        System.out.println(treeSet.contains(node1));
    53 
    54         int ans = 0;
    55         for (int i = 1; i <= q; i++) {
    56             Node node = new Node(i, a[i]);
    57             if (treeSet.contains(node)) {
    58                 treeSet.remove(node);
    59                 treeSet.add(new Node(nxt[i], a[i]));
    60             } else {
    61                 if (treeSet.size() == c) treeSet.pollFirst();
    62                 treeSet.add(new Node(nxt[i], a[i]));
    63                 ans++;
    64             }
    65         }
    66         System.out.println(ans);
    67     }
    68 
    69 }
    B

    C.C实验:复读机回到顶部

    题意

    输入一行文本s,输出s,在输出s wsl,要求用给定函数实现

    题解

    char* p = (char*)malloc(105*sizeof(char));复杂度O(105)

    PS:可能有空格,需要gets读入

    代码

    1 char *GetText(){
    2    char *p=(char*)malloc(105*sizeof(char));
    3    gets(p);
    4    return p;
    5 }
    C

    D.Robot Navigation回到顶部

    题意

    机器人从NWES出发到X,指令1往当前方向走x步,指令2右转,指令3左转,问到X的最少指令和方案数,n,m<=100

    题解

    最短路计数,dis[i][j][k]代表走到(i,j)方向是k的最短距离,cal表示方案数

    指令1相当于判断当前方向,然后走,如果为*就break

    指令2相当于+1%4,指令3相当于(-1+4)%4,复杂度O(4nm)

    PS:一直以为距离相同也要放进队列重新更新,然后就mle了,后来发现不需要,感谢黄bob

    ——相当于自带了一个bfs,保证了最短,无权的直接考虑层,有权的相当于用权值维护了一个层

    ——dij可以理解为堆优化的bfs,spfa是队列优化的,如果层数过多spfa炸了,但是dij活着

    ——但是如果出现负权,dij考权值搜索肯定炸了,但是spfa活着

    PS:为了不出现重复代码,可以把相同方法抽取出一个函数

    PS:测试了一下LinkedLists比ConcurrentLinkedQueue慢,所以最好还是用后面一个

    代码

     1 import java.util.*;
     2 
     3 public class Main {
     4 
     5     public static void main(String[] args) {
     6         Solution solver = new Solution();
     7         solver.solve();
     8     }
     9 
    10 }
    11 
    12 class Solution {
    13 
    14     private final int N = 105;
    15     private final int INF = 1000000000;
    16     private final long P = 1000000;
    17 
    18     private Queue<Integer> qx = new LinkedList<Integer>();
    19     private Queue<Integer> qy = new LinkedList<Integer>();
    20     private Queue<Integer> qdir = new LinkedList<Integer>();
    21     private char[][] g = new char[N][N];
    22     private int[][][] dis = new int[N][N][4];
    23     private long[][][] cal = new long[N][N][4];
    24 
    25     public void solve() {
    26         Scanner sc = new Scanner(System.in);
    27         while (sc.hasNext()) {
    28             int n = sc.nextInt();
    29             int m = sc.nextInt();
    30             if (n == 0 && m == 0) break;
    31             int sx = 0, sy = 0, sdir = 0, ex = 0, ey = 0;
    32 
    33             for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) for (int k = 0; k < 4; k++) {
    34                 dis[i][j][k] = INF;
    35                 cal[i][j][k] = 0;
    36             }
    37 
    38             for (int i = 0; i < n; i++) {
    39                 g[i] = sc.next().toCharArray();
    40                 for (int j = 0; j < m; j++) {
    41                     if (g[i][j] == 'N' || g[i][j] == 'E' || g[i][j] == 'S' || g[i][j] == 'W') {
    42                         sx = i; sy = j;
    43                         if (g[i][j] == 'N') sdir = 0;
    44                         else if (g[i][j] == 'E') sdir = 1;
    45                         else if (g[i][j] == 'S') sdir = 2;
    46                         else if (g[i][j] == 'W') sdir = 3;
    47                     } else if (g[i][j] == 'X') {
    48                         ex = i; ey = j;
    49                     }
    50                 }
    51             }
    52 
    53             bfs(n, m, sx, sy, sdir, ex, ey);
    54         }
    55     }
    56 
    57     private void bfs(int n, int m, int sx, int sy, int sdir, int ex, int ey) {
    58         qx.clear(); qy.clear(); qdir.clear();
    59         qx.add(sx); qy.add(sy); qdir.add(sdir);
    60         dis[sx][sy][sdir] = 0; cal[sx][sy][sdir] = 1;
    61         while (!qx.isEmpty()) {
    62             int ux = qx.poll(), uy = qy.poll(), udir = qdir.poll();
    63             //System.out.println("ux:" + ux + " uy:" + uy + " udir:" + udir + " dis:" + dis[ux][uy][udir]);
    64             // 上,右,下,左
    65             if (udir == 0) for (int i = ux - 1; i >= 0; i--) if (g[i][uy] == '*') break; else update(ux, uy, udir, i, uy, udir);
    66             else if (udir == 1) for (int i = uy + 1; i < m; i++) if (g[ux][i] == '*') break; else update(ux, uy, udir, ux, i, udir);
    67             else if (udir == 2) for (int i = ux + 1; i < n; i++) if (g[i][uy] == '*') break; else update(ux, uy, udir, i, uy, udir);
    68             else if (udir == 3) for (int i = uy - 1; i >= 0; i--) if (g[ux][i] == '*') break; else update(ux, uy, udir, ux, i, udir);
    69             // 右转
    70             update(ux, uy, udir, ux, uy, (udir + 1) % 4);
    71             // 左转
    72             update(ux, uy, udir, ux, uy, (udir + 3) % 4);
    73         }
    74         long minnDis = INF, ans = 0;
    75         for (int i = 0; i < 4; i++) if (minnDis > dis[ex][ey][i]) minnDis = dis[ex][ey][i];
    76         for (int i = 0; i < 4; i++) if (minnDis == dis[ex][ey][i]) ans = (ans + cal[ex][ey][i]) % P;
    77         System.out.println((minnDis == INF ? 0 : minnDis) + " " + ans);
    78     }
    79 
    80     // 更新答案
    81     private void update(int ux, int uy, int udir, int vx, int vy, int vdir) {
    82         if (dis[ux][uy][udir] + 1 < dis[vx][vy][vdir]) {
    83             dis[vx][vy][vdir] = dis[ux][uy][udir] + 1;
    84             cal[vx][vy][vdir] = cal[ux][uy][udir];
    85             qx.add(vx); qy.add(vy); qdir.add(vdir);
    86         } else if (dis[ux][uy][udir] + 1 == dis[vx][vy][vdir]) {
    87             cal[vx][vy][vdir] = (cal[vx][vy][vdir] + cal[ux][uy][udir]) % P;
    88         }
    89     }
    90 }
    D

    E.Rectangles回到顶部

    题意

    n个矩形嵌套,跟A题类似,求最多嵌套,n<=2000

    题解

    求最长路,分析一下可以知道是单向边和无环图,那么最长路就是放负权值的最短路,复杂度O(n^2)

    代码

     1 import java.util.*;
     2 
     3 public class Main {
     4 
     5     public static void main(String[] args) {
     6         Solution solver = new Solution();
     7         solver.solve();
     8     }
     9 
    10 }
    11 
    12 class Solution {
    13 
    14     private final int N = 1005;
    15 
    16     private List<List<Integer>> list = new ArrayList<>();
    17     private int[] d = new int[N];
    18     private Point[] p1 = new Point[N];
    19     private Point[] p2 = new Point[N];
    20     private Queue<Integer> q = new LinkedList<>();
    21     private int n;
    22 
    23     class Point {
    24         int x, y;
    25         Point(int x, int y) {
    26             this.x = x;
    27             this.y = y;
    28         }
    29     }
    30 
    31     public void solve() {
    32         Scanner sc = new Scanner(System.in);
    33         while (sc.hasNext()) {
    34             n = sc.nextInt();
    35             if (n == 0) break;
    36             list.clear();
    37             list.add(new ArrayList<>());
    38             for (int i = 1;i <= n; i++) {
    39                 p1[i] = new Point(sc.nextInt(), sc.nextInt());
    40                 p2[i] = new Point(sc.nextInt(), sc.nextInt());
    41                 list.add(new ArrayList<>());
    42             }
    43 
    44             for (int i = 1;i <= n; i++) {
    45                 for (int j = 1; j <= n; j++) {
    46                     if (check(i, j))
    47                         list.get(i).add(j);
    48                 }
    49             }
    50             for (int i = 1; i <= n; i++) list.get(0).add(i);
    51 
    52             System.out.println(dij());
    53         }
    54     }
    55 
    56     private boolean check(int i, int j) {
    57         return p2[i].x < p1[j].x && p2[i].y < p1[j].y;
    58     }
    59 
    60     private int dij() {
    61         d[0] = 0;
    62         for (int i = 1; i <= n; i++) d[i] = 1000000000;
    63         q.clear(); q.add(0);
    64         while (!q.isEmpty()) {
    65             int u = q.poll();
    66             for (int i = 0; i < list.get(u).size(); i++) {
    67                 int v = list.get(u).get(i);
    68                 if (d[v] > d[u] - 1) {
    69                     q.add(v);
    70                     d[v] = d[u] - 1;
    71                 }
    72             }
    73         }
    74         int ans = 0;
    75         for (int i = 1; i <= n; i++) ans = Math.max(ans, -d[i]);
    76         return ans;
    77     }
    78 }
    E

    F.悼念512汶川大地震遇难同胞――选拔志愿者回到顶部

    题意

    AB轮流捐钱,单次不超过m,总共捐到n结束,A开始

    题解

    简单博弈,如果n%(m+1)==0,由于A最多拿m,比如A拿了a,那么B只需要拿m+1-a,就可以让B赢,复杂度O(1)

    代码

     1 import java.util.*;
     2 
     3 public class Main {
     4 
     5     public static void main(String[] args) {
     6         Solution solver = new Solution();
     7         solver.solve();
     8     }
     9 
    10 }
    11 
    12 class Solution {
    13 
    14     public void solve() {
    15         Scanner sc = new Scanner(System.in);
    16         int c = sc.nextInt();
    17         for (int i = 0; i < c; i++) {
    18             int n = sc.nextInt();
    19             int m = sc.nextInt();
    20             if (n % (m + 1) == 0) System.out.println("Rabbit");
    21             else System.out.println("Grass");
    22         }
    23     }
    24     
    25 }
    F

    G.小强的Linux回到顶部

    题意

    给一个图,每个点需要时间,有依赖关系,问安装完n个点需要最少时间,n<=1000

    题解

    拓扑排序,首先取出时间最少的,把度数为0的所有点减掉最少时间,如果安装完就把这个点从图上去掉,并更新度数,复杂度O(n^2)

    代码

     1 import java.util.*;
     2 
     3 public class Main {
     4 
     5     public static void main(String[] args) {
     6         Solution solver = new Solution();
     7         solver.solve();
     8     }
     9 
    10 }
    11 
    12 class Solution {
    13 
    14     private final int N = 1005;
    15 
    16     private int[] d = new int[N];
    17     private int[] t = new int[N];
    18     private int[] vec = new int[N];
    19     private boolean[][] G = new boolean[N][N];
    20     private boolean[] vis = new boolean[N];
    21 
    22     public void solve() {
    23         Scanner sc = new Scanner(System.in);
    24         int n = sc.nextInt();
    25         for (int i = 1; i <= n; i++) t[i] = sc.nextInt();
    26         int m = sc.nextInt();
    27         for (int i = 1; i <= m; i++) {
    28             int u = sc.nextInt();
    29             int v = sc.nextInt();
    30             if (!G[v][u]) {
    31                 G[v][u] = true;
    32                 d[u]++;
    33             }
    34         }
    35 
    36         int sum = 0;
    37         for (int i = 1; i <= n; i++) {
    38             int minn = 1000000000;
    39             int tot = 0;
    40             for (int j = 1; j <= n; j++) {
    41                 if (!vis[j] && d[j] == 0) {
    42                     vec[tot++] = j;
    43                     minn = Math.min(minn, t[j]);
    44                 }
    45             }
    46             if (minn == 1000000000) break;
    47             for (int j = 0; j < tot; j++) {
    48                 t[vec[j]] -= minn;
    49                 if (t[vec[j]] == 0) {
    50                     vis[vec[j]] = true;
    51                     for (int k = 1; k <= n; k++) {
    52                         if (!vis[k] && G[vec[j]][k]) {
    53                             G[vec[j]][k] = false;
    54                             d[k]--;
    55                         }
    56                     }
    57                 }
    58             }
    59             sum += minn;
    60         }
    61 
    62         System.out.println(sum);
    63     }
    64 }
    G

    H.Unique Snowflakes回到顶部

    题意

    n个点,问最长连续的一段不存在重复的数字,n<=10^6

    题解

    这样想,如果a[l]=a[r],那么只需要去掉a[l],l+1往后还是满足的,复杂度O(n)

    PS:题意get错误2次,晕了

    代码

     1 import java.util.*;
     2 
     3 public class Main {
     4 
     5     public static void main(String[] args) {
     6         Solution solver = new Solution();
     7         solver.solve();
     8     }
     9 
    10 }
    11 
    12 class Solution {
    13 
    14     private HashMap<Integer, Integer> hashMap = new HashMap<>();
    15 
    16     public void solve() {
    17 
    18         Scanner sc = new Scanner(System.in);
    19         int t = sc.nextInt();
    20         for (int i = 0; i < t; i++) {
    21             hashMap.clear();
    22             int n = sc.nextInt();
    23             int maxl = 0, maxx = 0;
    24             for (int j = 0; j < n; j++) {
    25                 int x = sc.nextInt();
    26                 if (hashMap.containsKey(x))
    27                     maxl = Math.max(maxl, hashMap.get(x) + 1);
    28                 hashMap.put(x, j);
    29                 maxx = Math.max(maxx, j - maxl + 1);
    30             }
    31             System.out.println(maxx);
    32         }
    33     }
    34 }
    H

    I.Draw Something Cheat回到顶部

    题意

    n个长度12的大写串,问每个串都有的字母(会重复),n<=20

    题解

    每个串处理一个a[26],答案就是min(a[26]),复杂度O(n^2)

    PS:第一次没有get到重复这个坑

    代码

     1 import java.util.*;
     2 
     3 public class Main {
     4 
     5     public static void main(String[] args) {
     6         Solution solver = new Solution();
     7         solver.solve();
     8     }
     9 
    10 }
    11 
    12 class Solution {
    13 
    14     public void solve() {
    15 
    16         Scanner sc = new Scanner(System.in);
    17         int t = sc.nextInt();
    18         for (int i = 0; i < t; i++) {
    19             int n = sc.nextInt();
    20             int[] sum1 = new int[26];
    21             for (int j = 0; j < n; j++) {
    22                 String s = sc.next();
    23                 int[] sum2 = new int[26];
    24                 for (int k = 0; k < s.length(); k++) {
    25                     if (j == 0) sum1[s.charAt(k) - 'A']++;
    26                     else sum2[s.charAt(k) - 'A']++;
    27                 }
    28                 if (j != 0) {
    29                     for (int k = 0; k < 26; k++)
    30                         sum1[k] = Math.min(sum1[k], sum2[k]);
    31                 }
    32             }
    33             for (int j = 0; j < 26; j++)
    34                 for (int k = 0; k < sum1[j]; k++)
    35                     System.out.print((char) (j + 'A'));
    36             System.out.println();
    37         }
    38     }
    39 }
    I

    J.教堂回到顶部

    题意

    n*m个点,8个方向,距离1或sqrt(2),问走过每个点再回到起点的最短路

    题解

    如果n=1或m=1,那么就是走过去再走回来

    如果n为奇m为奇,那么需要走一个斜

    其余情况直接一次性走完

    代码

     1 import java.util.*;
     2 
     3 public class Main {
     4 
     5     public static void main(String[] args) {
     6         Solution solver = new Solution();
     7         solver.solve();
     8     }
     9 
    10 }
    11 
    12 class Solution {
    13     
    14     public void solve() {
    15         Scanner sc = new Scanner(System.in);
    16         while (sc.hasNext()) {
    17             double m = sc.nextDouble();
    18             double n = sc.nextDouble();
    19             if (m == 1) System.out.println(String.format("%.2f", (n - 1) * 2));
    20             else if (n == 1) System.out.println(String.format("%.2f", (m - 1) * 2));
    21             else if (n % 2 == 1 && m % 2 == 1) System.out.println(String.format("%.2f", n * m - 1 + Math.sqrt(2)));
    22             else System.out.println(String.format("%.2f", n * m));
    23         }
    24     }
    25 }
    J
  • 相关阅读:
    Insert into a Binary Search Tree
    Search in a Binary Search Tree
    Binary Search Tree Iterator
    Validate Binary Search Tree
    Serialize and Deserialize Binary Tree
    图的搜索
    codeforce vk cup2017
    hdu1160dp
    完全背包hdu1114
    最长递增子序列hdu1087
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/12771593.html
Copyright © 2011-2022 走看看