HNUST 1744: 安排辅导上机

1744: 安排辅导上机

时间限制: 1 Sec   内存限制: 128 MB
提交: 212   解决: 34
[ 提交][ 状态][ 讨论版]

题目描述

又到了辅导学弟学妹们上机的时候了,学长们都非常踊跃报名。那么问题来了,如何安排上机呢?

现在将问题简化一下:一共需要n节课(编号从1n)的辅导上机,正好有n位学长(编号从1n)报名,用二维矩阵A表示学长们的情况,A[i][j]表示第i个学长第第j节课是否有时间(1表示有时间,0表示忙)。为了进一步简化问题,假设一定存在将学长们按一定顺序排列后,前一位学长的合适时间集合包含后一位学长(也就是后一位学长哪节课有时间,那么前一位学长一定有时间,反过来就不一定了)。每节课都需要有学长辅导,同时为了满足大家辅导上机的热情,规定每个人恰好参与一次。现在问聪明的你能找到这样的方案吗?(能输出“Yes”,不行输出“No”)

输入

包含多组数据(数据组数小于200),每组数据第一行输入n1<=n<=20,表示有n节课需要辅导和n位学长报名,接下来是nn列矩阵表示学长们的情况(0表示忙,1表示有时间)。数据保证一定满足题目假设。

输出

   每组数据输出一行,能找到方案输出“Yes不能找到这样的方案输出“No”。

其实本题也是一个简单的模拟题,题意非常清晰了。

思路:因为   一定存在将学长们按一定顺序排列后,前一位学长的合适时间集合包含后一位学长 这句话看懂后就简单了。。。

所以我就对每节课扫描(从一开始),如果有学长有时间(并且有多个学长),我们就找到有时间最少的学长,把他安排在这儿。这样就可以最大限度的保证大家都能辅导。如果有哪节课没有学长了就是输出no,,,,我的代码是用结构体储存的,其实用二维数组也是一样的。贴代码咯

#include <iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
using namespace std;
typedef long long LL;

struct person
{
    int A[25];  ///st表示每一个学长,A【】表示学长对应得课有没有时间
    int sum;
} st[25];
bool cmp(person x,person y)  ///排个序,对有时间的课程数量按升序排列
{
    return x.sum<y.sum;
}
int main()
{
    int n,flag;
    while(scanf("%d",&n)==1)
    {
        memset(st,0,sizeof(st)); ///清空,下面注释掉的代码是我自己调试的时候测得。
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                scanf("%d",&st[i].A[j]);
                if(st[i].A[j]==1)
                    st[i].sum++;
            }
        }
        sort(st+1,st+n+1,cmp);
        /* for(int i=1;i<=n;i++)
         {
             for(int j=1;j<=n;j++)
             {
                 printf("%d ",st[i].A[j]);
             }
         printf("    sum=%d\n",st[i].sum);
         }*/
        for(int j=1; j<=n; j++)
        {
            flag=0;
            for(int i=1; i<=n; i++)
            {
                if(st[i].A[j]==1)
                {
                    //  printf("第%d行\n",i);
                    flag=1;
                    memset(st[i].A,0,sizeof(st[i].A)); ///把学长安排在这儿以后就清空他的时间
                    break;
                }
            }
            if(flag==0)
            {
                printf("No\n");
                break;
            }
        }
        /* for(int i=1;i<=n;i++)
         {
             for(int j=1;j<=n;j++)
             {
                 printf("%d ",st[i].A[j]);
             }
         printf("    sum=%d\n",st[i].sum);
         }*/

        if(flag) printf("Yes\n");
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值