题解

7 条题解

  • 1
    @ 2018-11-06 17:08:51
    //首先,最后一个人一定可以拿到自己最喜欢的球
    //然后,倒数第二个人只要不拿最后一个人要拿的小球,他就可以拿到自己最喜欢的
    //于是我们可以倒着考虑,每次让每个人从没有被拿的小球中拿自己最喜欢的
    //输入很贴心,省去了再排序的麻烦
    #include<cstdio>
    using namespace std;
    int c[60],map[60][60],pan[60],ans[60];
    int main()
    {
        int n,i,j,x;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
         scanf("%d",&c[i]);
        for(i=1;i<=n;i++)
         for(j=1;j<=n;j++)
          scanf("%d",&map[i][j]);
        for(i=n;i>0;i--)
         for(j=n;j>0;j--)
          if(!pan[map[i][j]])
           {
                pan[map[i][j]]=1;
                ans[i]=map[i][j];
                break;
           }
        for(i=1;i<=n;i++)
         printf("%d ",ans[i]);
        return 0;
    }
    
  • 0
    @ 2017-11-20 12:10:19
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <string>
    #include <cstring>
    #include <ciso646>
    #include <limits>
    using namespace std;
    
    
    
    inline int read()
    {
        int ans = 0, f = 1, c;
        c = getchar();
        while (!isdigit(c))
        {
            if (c == '-')
                f = -1;
            c = getchar();
        }
        while (isdigit(c))
        {
            ans = ans * 10 + c - 48;
            c = getchar();
        }
        return ans*f;
    }
    
    
    int main()
    {
        int n;
        int a[51][51];
        int b[51];
        bool inque[51];
    
        memset(inque, 0, sizeof(inque));
    
        n = read();
        int k;
        for (int i = 1;i <= n;i++)
            k = read();
        for (int i = 1;i <= n;i++)
            for (int j = 1;j <= n;j++)
                a[i][j] = read();
    
        for(int i=n;i>=1;i--)
            for (int j = n;j >= 1;j--)
            {
                if (!inque[a[i][j]])
                {
                    b[i] = a[i][j];
                    inque[a[i][j]] = true;
                    break;
                }
            }
        for (int i = 1;i <= n;i++)
            cout << b[i] << " ";
        cout << endl;
    
        system("pause");
        return 0;
    }
    

    首先是数据,一开始哪个球在哪个人手上并不影响最后的结果,接下来的n*n方阵,每行都是每个人对颜色的喜好顺序,最左边是最不喜欢的,最右边是最喜欢的。
    可以反过来考虑,第n个人一定能拿到自己最喜欢的球,第n-1个人最好情况是拿到最喜欢的球,最坏情况是拿到第二喜欢的球。依次类推到第1个人,最好情况是拿到最喜欢的球,最坏情况是拿到最不喜欢的球,事实上,在完全乱序的情况下,每个人都能拿到最喜欢的球。
    那么从最后一个人扫下来,用一个数组inque来记录被选过的球,遇到没选过的就拿走,记录到b中。
    依次输出即可

  • 0
    @ 2015-06-26 21:34:40

    注意一下“第i行第j列的正整数k代表:第i个人对颜色为k的球的喜爱程度是j"这句话啊
    语文不好的窝为此狂WA了好几次

  • 0
    @ 2012-09-23 12:51:23

    贪心秒杀...

  • 0
    @ 2012-09-23 12:19:48

    第i行第j列的正整数k代表:第i个人对颜色为k的球的喜爱程度是j

    不用排序 排序了 就只过2个点

  • 0
    @ 2012-09-23 11:43:34

    一开始被题目绕晕了,题意没理清楚,,

    后来想想,其实挺水的.

    对于第i个人来讲,他无论都想拿到一个喜欢程度大的小球,而这个小球又可能会被后面的(n-i)个人交换,那么这个人就需要交换一个(n-i-1)大的小球来保证以后不会被交换

    在做的时候我们可以从后往前扫 (这就是要转变一下思路),很容易实现

  • 0
    @ 2012-09-23 11:12:19

    就如官方题解所说,从后往前给这个人没有被选过的球中的喜爱值最大的,因此输入的第二行是不必要的。唯一需要注意的是喜爱值,不是第i行第j个是第i个人对第j个球的喜爱度k,而是第i个人喜爱度为j的球是k。

  • 1

信息

ID
1728
难度
4
分类
贪心 点击显示
标签
(无)
递交数
350
已通过
143
通过率
41%
被复制
2
上传者