1744: 安排辅导上机
时间限制: 1 Sec 内存限制: 128 MB提交: 212 解决: 34
[ 提交][ 状态][ 讨论版]
题目描述
又到了辅导学弟学妹们上机的时候了,学长们都非常踊跃报名。那么问题来了,如何安排上机呢?
现在将问题简化一下:一共需要n节课(编号从1到n)的辅导上机,正好有n位学长(编号从1到n)报名,用二维矩阵A表示学长们的情况,A[i][j]表示第i个学长第第j节课是否有时间(1表示有时间,0表示忙)。为了进一步简化问题,假设一定存在将学长们按一定顺序排列后,前一位学长的合适时间集合包含后一位学长(也就是后一位学长哪节课有时间,那么前一位学长一定有时间,反过来就不一定了)。每节课都需要有学长辅导,同时为了满足大家辅导上机的热情,规定每个人恰好参与一次。现在问聪明的你能找到这样的方案吗?(能输出“Yes”,不行输出“No”)
输入
包含多组数据(数据组数小于200),每组数据第一行输入n(1<=n<=20),表示有n节课需要辅导和n位学长报名,接下来是n行n列矩阵表示学长们的情况(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;
}