• codeforces 471B. MUH and Important Things 解题报告


    题目链接:http://codeforces.com/problemset/problem/471/B

    题目意思:有 n 个 tasks,编号依次为 1 ~ n,每个 task 都有一定的难度值来评估。例如,第 i 个 task 的难度值为 hi。现在的任务是把 n 个 task 全部完成,难度值越小的task越先完成。有3个人,都希望自己完成所有task的输出序列是与众不同的,问是否存在至少3条完成所有task的不同序列,没有的话输出 “NO”,否则输出“YES”并输出3条不同的完成序列。

         昨晚比赛的题目,有一点点思路,但最终调不出来,泪~~。

         小小的思路: 首先要知道有解的情况是什么。当时想到的是:两种情况。(1)相同难度值(difficulty)的task 至少有3个,类似这种序列:1 2 3 3 3 5  (2)相同 difficulty 的 task 有2个,但这种类型的task 至少有2个,类似这种序列: 1 2 2 4 4 5 

         不过处理起来确实复杂无比,甚至用到 vector 来存储每个难度值的邻接表,总的来说就是想得太复杂啦!!

         看了下别人的代码,发现思路其实是没有错的,还算是有一点点欣慰 ^_^

       首先判断是否能找到3条不同序列。用一个 used 数组来统计difficulty相同的task有多少个。处理的时候同常规办法有一点点不同,是先 used[h[i]] 再 count,但 used[h[i]]++在这条语句之后,这样处理的巧妙之处就是把我上面的两种情况都包括上去了,不用另外讨论。    

         另外,可以用pair<int, int> 来解决存储问题,first值保存task的difficulty,second值保存task的id。排序是很容易想到的,因为要按题目要求,难度值越少的task越先做嘛~~

         最后一个问题就是,如何得到3条不同的序列,用 swap 可以解决。由于排序之后,对于相同difficulty的task,它们的 id 默认是从小到大排序的,那么swap 的条件是,对于相同difficulty 的task,交换那些 后面 id > 前面 id 的task。可以知道,每交换一次,就得到一条新的完成序列。

         版本1(个人比较喜欢这个多点)

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 #define f first
     9 #define s second
    10 typedef pair<int, int> pii;
    11 
    12 const int maxn = 2000 + 10;
    13 pii task[maxn];
    14 int used[maxn];
    15 
    16 int main()
    17 {
    18     int n;
    19  //   freopen("input.txt", "r", stdin);
    20     while (scanf("%d", &n) != EOF)
    21     {
    22         int in, count = 0;
    23         memset(used, 0, sizeof(used));
    24         for (int i = 1; i <= n; i++)
    25         {
    26             scanf("%d", &in);
    27             task[i] = pii(in, i);  // 巧妙的赋值
    28             if (used[in])
    29                 count++;
    30             used[in]++;
    31         }
    32         if (count < 2)
    33             printf("NO
    ");
    34         else
    35         {
    36             printf("YES
    ");
    37             sort(task+1, task+1+n);  // 默认按pair first 排序
    38 
    39             for (int time = 0; time < 3; time++)
    40             {
    41                 for (int i = 1; i <= n; i++)
    42                     printf("%d ", task[i].s);
    43                 printf("
    ");
    44 
    45                 for (int i = 1; i < n; i++)
    46                 {
    47                     if (task[i].f == task[i+1].f && task[i].s < task[i+1].s)
    48                     {
    49                         swap(task[i], task[i+1]);
    50                         break;
    51                     }
    52                 }
    53             }
    54         }
    55     }
    56     return 0;
    57 }

         版本2(比赛时死也调不出来,看了别人的在原来基础上改的) 

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 const int maxn = 2000 + 10;
     9 struct node{
    10     int id;
    11     int h;
    12 }task[maxn];
    13 
    14 int cmp(node a, node b)
    15 {
    16     return a.h < b.h;
    17 }
    18 
    19 int cnt[maxn];
    20 
    21 int main()
    22  {
    23     int n;
    24  //   freopen("input.txt", "r", stdin);
    25     while (scanf("%d", &n) != EOF)
    26     {
    27         int t, c0 = 0;
    28         bool flag = false;
    29         memset(cnt, 0, sizeof(cnt));
    30         for (int i = 1; i <= n; i++)
    31         {
    32             scanf("%d", &t);
    33             task[i].h = t;
    34             task[i].id = i;
    35 
    36             if (cnt[t]) // 同一个h值出现3次以上/两个以上的h值出现2次以上
    37                 c0++;
    38             cnt[t]++;
    39         }
    40         if (c0 < 2)
    41             printf("NO
    ");
    42         else
    43         {
    44             printf("YES
    ");
    45             sort(task+1, task+1+n, cmp);
    46             for (int time = 0; time < 3; time++)
    47             {
    48                 for (int i = 1; i <= n; i++)
    49                     printf("%d ", task[i].id);
    50                 printf("
    ");
    51 
    52                 for (int i = 1; i < n; i++)
    53                 {
    54                     if (task[i].h == task[i+1].h && task[i].id < task[i+1].id)
    55                     {
    56                         swap(task[i], task[i+1]);
    57                         break;
    58                     }
    59                 }
    60             }
    61         }
    62     }
    63     return 0;
    64  }
  • 相关阅读:
    c# mvc action 跳转方式
    where T : new() 的含义
    HTML5 Dataset data-属性
    EF6 教程
    C写的AES(ECB/PKCS5Padding)
    【转载】openwrt: Makefile 框架分析
    SCP 命令【转】
    HTTP协议详解(转载)
    bootstrap模板
    拖拽插件
  • 原文地址:https://www.cnblogs.com/windysai/p/3997272.html
Copyright © 2020-2023  润新知