This repository has been archived on 2022-06-22. You can view files and clone it, but cannot push or open issues or pull requests.
usaco-guide/content/2_General/3_WhyCpp.md
2020-06-08 16:42:55 -04:00

5 KiB

slug title author order
/general/why-cpp Why C++? Benjamin Qi 3

A few reasons why choice of language matters significantly (outside of Bronze).

Time Limit

Although both Python and Java receive two times the C++ time limit in USACO, this is not the case for most other websites (ex. CodeForces). Even with the extended time limits, Python and Java sometimes have trouble passing.

  • Rewriting the C++ solution for USACO Silver Wormsort in Python receives TLE (Time Limit Exceeded) on 2/10 cases.

    Python3 8/10 Solution
    # 8/10 test cases ...
    
    fin = open("wormsort.in","r")
    lines = [line for line in fin]
    N,M = map(int,lines[0].split())
    p = list(map(lambda x: int(x)-1,lines[1].split()))
    
    ed = []
    for i in range(2,len(lines)):
      a,b,w = map(int,lines[i].split())
      a -= 1
      b -= 1
      ed.append([w,a,b])
    ed.sort()
    ed.reverse()
    
    adj = [[] for i in range(N)]
    vis = [0 for i in range(N)]
    cnt = 0
    
    def dfs(x):
      global cnt
      if vis[x] != 0:
        return
      vis[x] = cnt
      for i in adj[x]:
        dfs(i)
    
    def ok(mid):
      global cnt
      for i in range(N):
        vis[i] = 0
        adj[i].clear()
      for i in range(mid):
        a,b = ed[i][1],ed[i][2]
        adj[a].append(b)
        adj[b].append(a)
      for i in range(N):
        if vis[i] == 0:
          cnt += 1
          todo = [i]
          ind = 0
          while ind < len(todo):
            x = todo[ind] 
            ind += 1
            vis[x] = cnt
            for i in adj[x]:
              if vis[i] == 0:
                vis[i] = -cnt
                todo.append(i)
      ok = True
      for i in range(N):
        if vis[i] != vis[p[i]]:
          ok = False
      return ok
    
    lo,hi = 0,M
    while lo < hi:
      mid = (lo+hi)//2
      if ok(mid):
        hi = mid
      else:
        lo = mid+1
    
    fout = open("wormsort.out","w")
    
    fout.write(str(-1 if lo == 0 else ed[lo-1][0]))
    fout.write('\n')
    
  • A similar solution in Java requires almost 3s, which is fairly close to the time limit of 4s.

    Java Solution
    import java.io.*; // from Nick Wu
    import java.util.*;
    public class wormsort {
      public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new FileReader("wormsort.in"));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        loc = new int[n];
        component = new int[n];
        edges = new LinkedList[n];
        for(int i = 0; i < n; i++) edges[i] = new LinkedList<>();
        lhs = new int[m];
        rhs = new int[m];
        weight = new int[m];
        st = new StringTokenizer(br.readLine());
        for(int i = 0; i < n; i++) loc[i] = Integer.parseInt(st.nextToken())-1;
        for(int i = 0; i < m; i++) {
          st = new StringTokenizer(br.readLine());
          lhs[i] = Integer.parseInt(st.nextToken())-1;
          rhs[i] = Integer.parseInt(st.nextToken())-1;
          weight[i] = Integer.parseInt(st.nextToken());
        }
        br.close();
        int minW = 0;
        int maxW = 1000000001;
        while(minW != maxW) {
          int mid = (minW + maxW + 1) / 2;
          if(valid(mid)) minW = mid;
          else maxW = mid-1;
        }
        if(minW > 1e9) minW = -1;
        PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("wormsort.out")));
        pw.println(minW);
        pw.close();
      }
      static int[] loc, lhs, rhs, weight;
      static LinkedList<Integer>[] edges;
      static int[] component;
      private static void dfs(int curr, int label) {
        if(component[curr] == label) return;
        component[curr] = label;
        for(int child: edges[curr]) dfs(child, label);
      }
      private static boolean valid(int minW) {
        Arrays.fill(component, -1);
        for(int i = 0; i < edges.length; i++) edges[i].clear();
        for(int i = 0; i < lhs.length; i++) {
          if(weight[i] >= minW) {
            edges[lhs[i]].add(rhs[i]);
            edges[rhs[i]].add(lhs[i]);
          }
        }
        int numcomps = 0;
        for(int i = 0; i < component.length; i++) {
          if(component[i] < 0) {
            dfs(i, numcomps++);
          }
        }
        for(int i = 0; i < loc.length; i++) {
          if(component[i] != component[loc[i]]) return false;
        }
        return true;
      }
    }
    

Other

  • Python lacks a data structure that keeps its keys in sorted order (the equivalent of set in C++), which is required for some silver problems.
  • Java lacks features such as #define, typedef, and auto that are present in C++ (which some contestants rely on extensively).
  • Problemsetters don't always test Java solutions (and rarely Python) when setting the constraints.