• Sicily 7693. Cards 解题报告


    题目传送门:7693. Cards

     

    思路:

    1.  用数组b[m]和r[n]表示两组卡片,开一个bool类型的矩阵match,match[i][j]为true则表示b[i]和r[j]可以组成一对。

    2.  要得到最多的匹配对数,从最优的感觉上来看可以求出每张卡片在另一组有多少卡片与之匹配,然后每次从蓝色组中找出匹配数最少的那张卡,并在与那张卡匹配的红组卡中找出匹配数最少的那一张组成一队消除。这样考虑的理由是:匹配数多是卡即使消去了与之匹配的其中一些卡,还有剩下的卡可以匹配,因此先消去匹配数最小的卡。

    3.  为了找到当前匹配数最少的那2张卡,开数组num_of_matches_b[m]记录每张蓝色卡当前的匹配数,num_of_matched_r[n]记录每张红色卡当前的匹配数。匹配数若为0则表示另一组没有卡与该卡组成一对。每次从蓝色卡中找出匹配数最小且非零的那张,记录下标index_b,然后从与之匹配的红色卡中找出匹配数最小的那张,记录下标index_r。将该对消除后,match[i][j]变为false,并将于这两张卡匹配的所有卡的匹配数减一(因为这两张卡已经不能再利用)。

     

    代码:

     1 #include <iostream>
     2 #include <memory.h>
     3 using namespace std;
     4 
     5 int gcd(int x, int y){
     6     int temp;
     7     if(x < y){
     8         temp = x, x = y, y = temp;
     9     }
    10     while(y != 0){
    11         temp = x % y, x = y, y = temp;
    12     }
    13     return x;
    14 }
    15 bool match(const int &a, const int &b){
    16     if(gcd(a, b) > 1)
    17         return true;
    18     else
    19         return false;
    20 }
    21 
    22 int main(){
    23     int m, n;
    24     while(cin >> m >> n && (m != 0 || n != 0)){
    25         int b[m], r[n], num_of_matches_b[m], num_of_matches_r[n];
    26         bool match_matrix[m][n];//match_matrix[i][j] will be true if b[i] match r[j].
    27         memset(num_of_matches_b, 0, sizeof(num_of_matches_b));
    28         memset(num_of_matches_r, 0, sizeof(num_of_matches_r));
    29         for(int i = 0; i < m; ++i){
    30             memset(match_matrix[i], false, sizeof(match_matrix[i]));
    31         }
    32         for(int i = 0; i < m; ++i)
    33             cin >> b[i];
    34         for(int i = 0; i < n; ++i)
    35             cin >> r[i];
    36         for(int i = 0; i < m; ++i){
    37             for(int j = 0; j < n; ++j){
    38                 if(match(b[i], r[j])){
    39                     match_matrix[i][j] = true;
    40                     num_of_matches_b[i]++;
    41                     num_of_matches_r[j]++;
    42                 }
    43             }
    44         }
    45         int min = n + 1,  //The most matches of a blue card will not exceed n.
    46         result = 0, index_b, index_r;//b[index_b] and r[index_r] is the pair of cards to be removed.
    47         for(int i = 0; i < m; ++i){//find index_b
    48             if(num_of_matches_b[i] > 0 && num_of_matches_b[i] < min){
    49                 min = num_of_matches_b[i];
    50                 index_b = i;
    51             }
    52         }
    53         if(min == n + 1)  //No such pair
    54             cout << 0 << endl;
    55         else{
    56             while(min != n + 1){
    57                 result++;
    58                 //There still exist one pair at least.
    59                 min = m + 1;  //The most matches of a red card will not exceed m.
    60                 for(int i = 0; i < n; ++i){//Find index_r
    61                     if(match_matrix[index_b][i] && num_of_matches_r[i] < min){
    62                         index_r = i;
    63                         min = num_of_matches_r[i];
    64                     }
    65                 }
    66                 for(int i = 0; i < m; ++i){
    67                     if(match_matrix[i][index_r]){
    68                         num_of_matches_b[i]--;
    69                         match_matrix[i][index_r] = false;
    70                     }
    71                 }
    72                 for(int i = 0; i < n; ++i){
    73                     if(match_matrix[index_b][i]){
    74                         match_matrix[index_b][i] = false;
    75                         num_of_matches_r[i]--;
    76                     }
    77                 }
    78                 num_of_matches_b[index_b] = 0;
    79                 num_of_matches_r[index_r] = 0;
    80                 //Renew min
    81                 min = n + 1;
    82                 for(int i = 0; i < m; ++i){
    83                     if(num_of_matches_b[i] > 0 && num_of_matches_b[i] < min){
    84                         min = num_of_matches_b[i];
    85                         index_b = i;
    86                     }
    87                 }
    88             }
    89             cout << result << endl;
    90         }
    91     }
    92     return 0;
    93 }
  • 相关阅读:
    1115:直方图
    1114:白细胞计数
    1114:白细胞计数
    忘记mysql密码后重置密码
    pycharm中无法导入pip安装的包
    win7升级win10
    WIN7 Windows update提示不支持硬件
    getcwd() 和 os.path.realpath () 的区别
    selenium启动chrome时,弹出设置页面:Windows Defender 防病毒要重置您的设置
    ui测试如何检测页面差异
  • 原文地址:https://www.cnblogs.com/jolin123/p/3633135.html
Copyright © 2020-2023  润新知