zoukankan      html  css  js  c++  java
  • codeforces 140B.New Year Cards 解题报告

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

    题目意思:给出 Alexander 和他的 n 个朋友的 preference lists:数字 1~n 的排列。现在Alexander 需要遵循两条rules向他的 朋友发送贺卡。

    1、他不会send 和 该朋友给他的一模一样的贺卡。

    2、对于当前他所拥有的贺卡,他只会选择他自己最喜欢的卡给朋友。

        同一张卡可以使用多次,而且尽量使得他的朋友满意,也就是尽量满足该朋友的 preference lists。

        现在需要找出一条 send card 的 schedule,表示某个 moment 下应该send card 到某个friend中。

        正如题解所说,这条题目难就难在模拟上。因为Alexander 某个时刻的决策受到两个因素的影响:他自己本人的preference list  以及他朋友的preference list 的影响。而且 Alexander 的preference list 随着时间的推移是有所改变的。所以我们希望在尽量不使得他朋友的preference list 太差的情况下,按照题目所说的,运用那两条rule.

        排除 send 同 receive 是同 一 张卡并不困难,因为 编号为 i 的人send card 的时刻正是 i ,也就是编号为 i 的卡!不等于 i 即可。然后就是考虑对该朋友应该send 哪张卡了:对朋友的preference list 的每个数都check 下 Alexander 的preference list 中哪个数可以派发。(说不下去了,以下是请教乌冬子后整理的)

         引用如下(白话文,请见谅),思路代码都非常清晰!

         /*****************************

         对于每个朋友,都枚举出所有alex可能发出既卡片,然后从中选出呢个朋友比较中意既就得

         其实喜爱列表作用就系话比我地知,有滴卡系永远唔会寄出去

         我地用朋友既角度去捻,最好既结果就系拿到alex可能寄出卡里面,自己最喜爱果张

         注意到alex可以系任何时刻发卡片,所以枚举可能寄出卡片方法就系求出alex每日会寄出既卡片就得,因为有rule2所以我地要针对每个人求,例如,第一个例子,对于朋友1,alex每日寄出既卡系0,2,3,3,3,对于朋友2,每日寄出既卡片系1,1,3,3,3,朋友3系1,1,3,3,3 如此类推

        ********************************/

         他的代码,就是按这个思路写的,我改了下下标,省去了一些处理,命名也改了下。

        

     1 #include <cstdlib>
     2 #include <cstdio>
     3 #include <iostream>
     4 #include <vector>
     5 using namespace std;
     6 
     7 const int N = 3e2 + 10;
     8 
     9 int n, fri_pref[N][N];
    10 
    11 int main()
    12 {
    13   cin.sync_with_stdio(0);
    14   while (cin >> n) {
    15     for (int i = 1; i <= n; i++)
    16       for (int j = 1; j <= n; j++) {
    17         cin >> fri_pref[i][j];
    18       }
    19 
    20     int Alex_pref[N];
    21     for (int i = 1; i <= n; i++) {
    22       int input;
    23       cin >> input;
    24       Alex_pref[input] = i;   // 标出Alex表的喜好编号顺序
    25     }
    26 
    27     int res[N];
    28     for (int i = 1; i <= n; i++)   //
    29     {
    30         bool h[N] = {false};
    31         int now = -1;
    32         for (int j = 1; j <= n; j++)  // Alex 表
    33         {
    34           if (j == i || (~now && Alex_pref[j] > Alex_pref[now]))  // ~now 即 now != -1,枚举Alex每日对i这个人寄出的卡片,且排除了Alex一定派不出去的卡
    35               continue;
    36           now = j;
    37           h[now] = true;
    38         }
    39 
    40         for (int j = 1; j <= n; j++)
    41         {
    42           if (!h[fri_pref[i][j]])
    43             continue;
    44           res[i] = fri_pref[i][j];
    45           break;
    46         }
    47     }
    48 
    49     for (int i = 1; i < n; i++)
    50       cout << res[i] << " ";
    51     cout << res[n] << endl;
    52   }
    53 
    54   return 0;
    55 }

       

  • 相关阅读:
    ios 关闭自动修正输入内容
    Tarjan+缩点【强连通分量】【模板】
    初识Tarjan算法
    【尺取法】【转】
    【先加后减拼凑思想】【合成数问题】
    强连通分量【k 算法、t 算法】
    大数【加减乘除】
    洛谷博客地址【置顶!】
    差分约束+spfa【模板】
    【poj3169】【差分约束+spfa】
  • 原文地址:https://www.cnblogs.com/windysai/p/3960430.html
Copyright © 2011-2022 走看看