• topcoder srm 525 div1


    problem1 link

    最后剩下的是中间的一个矩形.所以可以直接枚举这个矩形,如果它含有的硬币个数等于$K$,则再计算移动的最少次数,更新答案.

    problem2 link

    首先,每个节点发送每种消息最多只发送一次;其次,在得到消息之后一定是马上发送而不是等待一会儿再发送;最后一点是,如果第$i$天发送了一种消息,一定可以在第$i+1$天发送另外一种消息.

    现在的问题是,一个节点同时有两种消息时,应该首先发送哪一种.这个可以$2^{n}$枚举第一次发送的消息类型,然后模拟即可.在模拟过程中可能会出现先来的消息不是枚举的第一次发送的类型.这个可以直接结束这种情况,因为一定会枚举到一种情况,其他节点都一样,而这个节点是先发送另一种状态.

    problem3 link

    首先,如果将给出的矩阵看作是$n$个顶点的有向图,那么交换$i,j$行列得到的新图相当于两个顶点交换标号,即顶点$i$变为$j$,顶点$j$变为$i$.

    那么题目就是要对给出的图重新标号,使得与目标图匹配.

    对于$n=8$来说,如果画出目标图,是下面的样子:

    设$p_{i}$表示目标图的第$i$个顶点是原图的第$p_{i}$个顶点.那么对于$n=8$来说,确定了$p_{0},p_{1},p_{n-1}$后,与$p_{1}$相连且不与$p_{n-1}$相连的就是$p_{2}$,同时与$p_{1}$和$p_{n-1}$相连的是$p_{6}$.

    也就是说由$p_{1},p_{7}$可找到$p_{2},p_{6}$.同理,由$p_{2},p_{6}$可找到$p_{3},p_{5}$,最后就是$p_{4}$.查找的过程如下图所示(第一幅图找到$p_{2},p_{6}$,第二幅图找到$p_{3},p_{5}$)

    最后一个问题就是如果有了这个数组$p$,求最少的交换次数.$p$中的数组组成了若干个环,对于每个环$C$,需要的交换次数为$|C|-1$

    code for problem1

    #include <vector>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    class DropCoins {
      public:
        int getMinimum(vector <string> board, int K) {
          const int n = (int)board.size();
          const int m = (int)board[0].size();
          int result = -1;
          vector<vector<int>> f(n + 1, vector<int>(m + 1, 0));
          for (int i = 1; i <= n; ++ i) {
            for (int j = 1; j <= m; ++ j) {
              f[i][j] = f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1];
              if (board[i - 1][j - 1] == 'o') {
                ++ f[i][j];
              }
            }
          }
          for (int left = 1; left <= m; ++ left) {
            for (int right = left; right <= m; ++ right) {
              for (int up = 1; up <= n; ++ up) {
                for (int down = up; down <= n; ++ down) {
                  int cnt = f[down][right] - f[down][left - 1] - f[up - 1][right]
                    + f[up - 1][left - 1];
                  if (cnt == K) {
                    int cost = Cost(left - 1, m - right) + Cost(up - 1, n - down);
                    if (result == -1 || result > cost) {
                      result = cost;
                    }
                  }
                }
              }
            }
          }
          return result;
        }
    
      private:
        int Cost(int x, int y) {
          return std::min(x + x + y, x + y + y);
        }
    };

    code for problem2

    #include <iostream>
    #include <string>
    #include <vector>
    using namespace std;
    
    class Rumor {
      public:
      int getMinimum(string knowledge, vector<string> graph)
      {
        const int n = (int)graph.size();
        int result = -1;
        for (int mask = 0; mask < (1 << n); ++ mask) {
          int cost = calculate(mask, knowledge, graph);
          if (cost != -1 && (result == -1 || result > cost)) {
            result = cost;
          }
        }
        return result;
      }
    
      private:
    
      int getFirstType(int mask, int i) {
        return (mask & (1 << i)) ? 2 : 1;
      }
      int getSecondType(int mask, int i) {
        return (mask & (1 << i)) ? 1 : 2;
      }
      int calculate(const int mask, const string& knowledge, 
          const vector<string>& graph) {
        const int n = (int)knowledge.size();
        long long preGetMessageState = 0;
        long long currentKnowMessageState = 0;
        int preBroadcastMask = 0;
        int day = 0;
        for (int i = 0; i < n; ++ i) {
          if (knowledge[i] == 'Y') {
            preGetMessageState |= 3ll << (i << 1);
          }
        }
        int sendedMessageMask = 0;
        currentKnowMessageState = preGetMessageState;
        const long long finalState = (1ll << (n + n)) - 1;
        while (currentKnowMessageState != finalState) {
          ++ day;
          int nowBroadcastState = 0;
          long long nowGetMessageState = 0;
          for (int i = 0; i < n; ++ i) {
            int type = -1;
            if (preBroadcastMask & (1 << i)) {
              type = getSecondType(mask, i);
            }
            else if (!(sendedMessageMask & (1 << i))) {
              int t = (preGetMessageState >> (i + i)) & 3;
              if (t != 0) {
                if (t & getFirstType(mask, i)) {
                  type = getFirstType(mask, i);
                }
                else {
                  return -1;
                }
              }
            }
            if (type == -1) {
              continue;
            }
            for (int j = 0; j < n; ++ j) {
              if (graph[i][j] == 'Y') {
                nowGetMessageState |= ((long long)type) << (j + j);
              }
            }
            if (type == getSecondType(mask, i)) {
              sendedMessageMask |= 1 << i;
            }
            else {
              nowBroadcastState |= 1 << i;
            }
          }
          long long currentAll = currentKnowMessageState | nowGetMessageState;
          if (currentAll == currentKnowMessageState) {
            return -1;
          }
          currentKnowMessageState = currentAll;
          preGetMessageState = nowGetMessageState;
          preBroadcastMask = nowBroadcastState;
        }
        return day;
      }
    };

    code for problem3

    #include <vector>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    
    class MonochromePuzzle {
      public: 
        int getMinimum(vector <string> board) {
          const int n = (int)board.size();
          for (int i = 0; i < n; ++ i) {
            int cnt = 0;
            for (int j = 0; j < n; ++ j) {
              if (board[i][j] == '#') {
                ++ cnt;
              }
            }
            if (cnt != 3) {
              return -1;
            }
          }
          int result = -1;
          for (int i = 0; i < n; ++ i) {
            for (int j = 0; j < n; ++ j) {
              if (i == j) {
                continue;
              }
              for (int k = 0; k < n; ++ k) {
                if (k == i || k == j) {
                  continue;
                }
                if (board[i][j] != '#' || board[i][k] != '#') {
                  continue;
                }
                int tmp = calculate(i, j, k, board);
                if (tmp != -1 && (result == -1 || result > tmp)) {
                  result = tmp;
                }
              }
            }
          }
          return result;
        }
      private:
        int calculate(const int p0, const int p1, const int p2,
            const vector<string>& board) {
          const int n = (int)board.size();
          vector<int> p(n, 0);
          vector<int> used(n, 0);
          p[0] = p0;
          p[1] = p1;
          p[n - 1] = p2;
          used[p0] = used[p1] = used[p2] = 1;
          int x = 1, y = n - 1;
          int a = 2, b = n - 2;
          while (a < b) {
            int ta = -1, tb = -1;
            for (int i = 0; i < n; ++ i) {
              if (used[i] == 0 && board[p[x]][i] == '#') {
                if (board[p[y]][i] == '#') {
                  tb = i;
                }
                else {
                  ta = i;
                }
              }
            }
            if (ta == -1 || tb == -1) {
              return -1;
            }
            p[a] = ta;
            p[b] = tb;
            used[ta] = used[tb] = 1;
            x = a ++;
            y = b --;
          }
          for (int i = 0; i < n; ++ i) {
            if (used[i] == 0 && board[p[x]][i] == '#' && 
                board[p[y]][i] == '#' && board[p[n - 1]][i] == '#') {
               p[a] = i;
               return getCost(p);
            }
          }
          return -1;
        }
        int getCost(const vector<int>& p) {
          const int n = (int)p.size();
          vector<int> visited(n, 0);
          int result = n;
          for (int i = 0; i < n; ++ i) {
            if (visited[i]) {
              continue;
            }
            int current = i;
            while (visited[current] == 0) {
              visited[current] = 1;
              current = p[current];
            }
            result -= 1;
          }
          return result;
        }
    };
    

      

  • 相关阅读:
    JAVA基础——异常详解
    Android Studio如何配置adb以及常用命令
    利用Android Studio编写 Android上的c与c++程序
    启动与销毁Activity
    应用资源概览
    Android 开发者文档 -- 应用基础知识
    51单片机最小系统
    同相放大器
    反相放大器
    面向对象开发C++快速入门视频教程 C++基础加实战视频教程
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/8366732.html
Copyright © 2020-2023  润新知