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  }
原文地址:https://www.cnblogs.com/windysai/p/3997272.html