• topcoder srm 705 div1


    problem1 link

    设有一个字母表$T$,对于一个单词$w$,若对于任意的$0leq i< |w|-1$,满足$w_{i}$在$T$中的排名小于等于$w_{i+1}$在$T$中的排名,则称$s$在$T$中是合法的。给出一个仅包含小写字母的单词集合$S$,重新排列字母表$T$得到新的字母表$T^{'}$,使得$S$中每个单词在$T^{'}$下是合法的。问是否存在这样的$T^{'}$。

    建立有向图。不存在环即可。可以拓扑排序或者用floyd判断。

    problem2 link

    有n个盒子。每个盒子有1个糖。有一个大小为$n*m$转换矩阵$T$。进行$10^{100}$次操作,每次操作如下:(1)选择一个$j,0leq j< m$,对所有的$i,0leq i< n$,将第$i$个盒子的糖倒入到第$T[i][j]$个盒子。问最后最少有几个盒子中有糖?

    首先,每进行一次操作,有糖的盒子的数目不会变多。其次,假设一开始进行的操作序列为$S$,设这时候的状态为$x$,然后进行一个操作序列$P$,随后再进行一个操作序列$S$,设这时候的状态为$y$,那么$y$时有糖的盒子是状态$x$时有糖的盒子的子集。

    基于这两个结果,操作的流程为:判断当前是否存在两个盒子,使得经过某个操作序列$P$后,这两个盒子在操作后合并到同一个盒子,那么就执行该操作序列$P$。直到不存在这样的两个盒子即可。

    problem3 link

    首先,按照每个灯进行高斯消元. 假设$m=5, n =8$,最后的样子假设如下

    egin{pmatrix}
    1 & 0& 0& 0& 0& 0 & 0 & 0\
    0 & 1& 0& 0& 0& 0& 0& 0\
    0 & 0& 1& 0& 0& 0& 0& 0\
    1 & 1 & 0 & 0& 0 & 0 & 0& 0\
    0 & 0 & 1& 0& 0& 0& 0& 0
    end{pmatrix}

    那么最后五个操作(最后五列)有没有都可以, 最后的答案乘以$2^{5}$就可以了.

    现在的rank, $r=3$.如果r比较小,那么直接进行$2^{r}$的暴力枚举即可.否则,对剩下的$m-r$行进行dp即可.复杂度为$r*2^{m-r}$

    code for problem1

    #include <string>
    #include <vector>
    
    class AlphabetOrderDiv1 {
    public:
      std::string isOrdered(const std::vector<std::string> &words) {
        int g[26][26];
        for (int i = 0; i < 26; ++i) {
          for (int j = 0; j < 26; ++j) {
            g[i][j] = i == j;
          }
        }
        for (const auto &s : words) {
          for (size_t j = 0; j + 1 < s.length(); ++j) {
            int x = s[j] - 'a';
            int y = s[j + 1] - 'a';
            g[x][y] = 1;
          }
        }
        for (int i = 0; i < 26; ++i) {
          for (int j = 0; j < 26; ++j) {
            for (int k = 0; k < 26; ++k) {
              g[j][k] |= g[j][i] & g[i][k];
            }
          }
        }
    
        for (int i = 0; i < 26; ++i) {
          for (int j = 0; j < i; ++j) {
            if (g[i][j] != 0 && g[j][i] != 0)
              return "Impossible";
          }
        }
        return "Possible";
      }
    };

    code for problem2

    #include <algorithm>
    #include <vector>
    
    class MovingTokens {
    public:
      int move(int n, int m, const std::vector<int> &moves) {
        Init(n, m, &A);
        for (int i = 0; i < n; ++i) {
          for (int j = 0; j < m; ++j) {
            A[i][j] = moves[j * n + i];
          }
        }
        this->n = n;
        this->m = m;
        Init(n, n, &f);
        std::vector<int> a(n, 1);
        while (true) {
          bool ok = false;
          std::vector<int> path;
          for (int i = 0; i < n && !ok; ++i) {
            for (int j = i + 1; j < n && !ok; ++j) {
              if (a[i] != 0 && a[j] != 0) {
                ++K;
                path.clear();
                if (Dfs(i, j, &path)) {
                  std::reverse(path.begin(), path.end());
                  ok = true;
                }
              }
            }
          }
          if (!ok) {
            break;
          }
          Transform(path, &a);
        }
    
        int cnt = 0;
        for (int i = 0; i < n; ++i) {
          if (a[i] != 0) {
            ++cnt;
          }
        }
        return cnt;
      }
    
    private:
      bool Dfs(int x, int y, std::vector<int> *path) {
        if (x == y) {
          return true;
        }
        if (f[x][y] == K) {
          return false;
        }
        f[x][y] = K;
        for (int j = 0; j < m; ++j) {
          if (Dfs(A[x][j], A[y][j], path)) {
            path->emplace_back(j);
            return true;
          }
        }
        return false;
      }
    
      void Transform(const std::vector<int> &path, std::vector<int> *a) {
        std::vector<int> b(n);
        for (int j : path) {
          for (int i = 0; i < n; ++i) {
            b[i] = a->at(i);
            a->at(i) = 0;
          }
          for (int i = 0; i < n; ++i) {
            a->at(A[i][j]) += b[i];
          }
        }
      }
    
      void Init(int n, int m, std::vector<std::vector<int>> *a, int init = 0) {
        a->resize(n);
        for (int i = 0; i < n; ++i) {
          a->at(i).resize(m, init);
        }
      }
    
      std::vector<std::vector<int>> A;
      std::vector<std::vector<int>> f;
      int n, m;
    
      int K = 0;
    };

    code for problem3

    #include <string>
    #include <vector>
    
    class BrightLampsRemake {
    public:
      std::vector<long long> maxAndCount(const std::string &init,
                                         const std::vector<std::string> &buttons) {
        int n = static_cast<int>(buttons.size());
        int m = static_cast<int>(init.size());
        std::vector<int> a(m);
        for (int i = 0; i < m; ++i) {
          a[i] = init[i] - '0';
        }
        std::vector<std::vector<int>> b(m, std::vector<int>(n, 0));
        for (int i = 0; i < m; ++i) {
          for (int j = 0; j < n; ++j) {
            b[i][j] = buttons[j][i] - '0';
          }
        }
        int rank = 0;
        while (true) {
          int new_row = -1;
          int new_col = -1;
          for (int i = rank; i < m && new_row == -1; ++i) {
            for (int j = rank; j < n; ++j) {
              if (b[i][j] != 0) {
                new_row = i;
                new_col = j;
                break;
              }
            }
          }
          if (new_row == -1) {
            break;
          }
          if (new_row != rank) {
            for (int i = 0; i < n; ++i) {
              std::swap(b[rank][i], b[new_row][i]);
            }
            std::swap(a[rank], a[new_row]);
          }
          if (new_col != rank) {
            for (int i = 0; i < m; ++i) {
              std::swap(b[i][new_col], b[i][rank]);
            }
          }
          for (int i = 0; i < n; ++i) {
            if (b[rank][i] != 0 && i != rank) {
              for (int j = 0; j < m; ++j) {
                b[j][i] ^= b[j][rank];
              }
            }
          }
          ++rank;
        }
        if (rank <= 27) {
          std::vector<long long> mask(rank, 0);
          for (int i = 0; i < rank; ++i) {
            for (int j = 0; j < m; ++j) {
              if (b[j][i] != 0) {
                mask[i] |= 1ll << j;
              }
            }
          }
          long long c = 0;
          for (int i = 0; i < m; ++i) {
            if (a[i] != 0) {
              c |= 1ll << i;
            }
          }
          std::vector<long long> result = {-1, -1};
          Dfs(0, c, mask, rank, &result);
          result[1] <<= n - rank;
          return result;
        }
        int p = m - rank;
        struct Node {
          int num = -1;
          int h = 0;
          long long c = -1;
        };
        std::vector<std::vector<Node>> dp(2, std::vector<Node>(1 << p));
        std::vector<int> c(rank, 0);
        for (int i = 0; i < rank; ++i) {
          for (int j = rank; j < m; ++j) {
            if (b[j][i] != 0) {
              c[i] |= 1 << (j - rank);
            }
          }
        }
        int x = 0;
        for (int i = rank; i < m; ++i) {
          if (a[i] != 0) {
            x |= 1 << (i - rank);
          }
        }
        dp[0][x].num = 0;
        dp[0][x].c = 1;
        int H = 0;
        int prev = 0;
        int curr = 1;
        auto Update = [&](int a, long long b, int h, Node *r) {
          if (r->h != h || a > r->num) {
            r->num = a;
            r->c = b;
            r->h = h;
          } else if (a == r->num) {
            r->c += b;
          }
        };
    
        for (int i = 0; i < rank; ++i) {
          for (int j = 0; j < (1 << p); ++j) {
            const auto &e = dp[prev][j];
            if (e.h != H || e.num < 0) {
              continue;
            }
            Update(e.num + 1 - a[i], e.c, H + 1, &(dp[curr][j ^ c[i]]));
            Update(e.num + a[i], e.c, H + 1, &(dp[curr][j]));
          }
          std::swap(curr, prev);
          ++H;
        }
        Node result;
        result.h = H;
        for (int i = 0; i < (1 << p); ++i) {
          if (dp[prev][i].h == H && dp[prev][i].num >= 0) {
            Update(dp[prev][i].num + GetNum(i), dp[prev][i].c, H, &result);
          }
        }
        return {result.num, result.c << (n - rank)};
      }
    
    private:
      int GetNum(long long x) { return __builtin_popcountll(x); }
      void Dfs(int cur_depth, long long v, const std::vector<long long> &mask,
               int max_depth, std::vector<long long> *result) {
        if (cur_depth == max_depth) {
          long long t = GetNum(v);
          if (result->front() == t) {
            ++result->back();
          } else if (result->front() < t) {
            result->front() = t;
            result->back() = 1;
          }
        } else {
          Dfs(cur_depth + 1, v ^ mask[cur_depth], mask, max_depth, result);
          Dfs(cur_depth + 1, v, mask, max_depth, result);
        }
      }
    };
  • 相关阅读:
    vbs下载文件
    变量名自动变化
    VBS获得随机数,截图函数
    VBS定时关闭的弹窗
    VBS操作剪切板
    手动关闭端口
    win7,xp通用的打开文件浏览对话框的方法
    QTP全选页面的复选框
    SVN的使用
    工作中用到的前端内容整理
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/6519279.html
Copyright © 2020-2023  润新知