题目如下:
学校新建了宿舍楼,共有 n 间寝室。等待分配的学生中,有女生 n0 位、男生 n1 位。所有待分配的学生都必须分到一间寝室。所有的寝室都要分出去,最后不能有寝室留空。
现请你写程序完成寝室的自动分配。分配规则如下:
- 男女生不能混住;
- 不允许单人住一间寝室;
- 对每种性别的学生,每间寝室入住的人数都必须相同;例如不能出现一部分寝室住 2 位女生,一部分寝室住 3 位女生的情况。但女生寝室都是 2 人一间,男生寝室都是 3 人一间,则是允许的;
- 在有多种分配方案满足前面三项要求的情况下,要求两种性别每间寝室入住的人数差最小。
输入格式:
输入在一行中给出 3 个正整数 n0、n1、n,分别对应女生人数、男生人数、寝室数。数字间以空格分隔,均不超过 105。
输出格式:
在一行中顺序输出女生和男生被分配的寝室数量,其间以 1 个空格分隔。行首尾不得有多余空格。
如果有解,题目保证解是唯一的。如果无解,则在一行中输出 No Solution
。
———————————————————————————————————————————
以下为我自己的思路:
首先,由题目得,有以下限制条件:
1、寝室不能是单人间
2、各性别的每间寝室人数一致
3、满足1和2的情况下男女每间寝室人数差最少
根据限制条件,对此题我有以下解题思路:
1、男女性别在分配寝室方面没有区别,且男女人数无法确定,因此以人数少者优先进行考虑,将男、女中人数较少的一边赋值给X,设置一个for循环,用于整除人数较少的一边,for循环的参数i从2开始,到X结束,每次+1
2、判断结束条件:当i==n的时候,说明其中某个性别分到了所有的房间,条件结束,跳出循环
3、计数条件:当男生对n-i取余,女生对i取余,余数均为0时,设置flag和FLAG,FLAG=1表示整个循环中至少有一个分配方案,flag=1表示在某次循环内找到一个分配方案
4、判断条件:将分配方案i暂存到temp中,再设置对比变量com存储第i钟分配情况男女寝室人数差,设置参数对比变量tempcom,存储循环中最小的人数差的分配方案,若com比tempcom小,则tempcom更新,设置result存储人数差最少的分配方案i
5、输出部分:若FLAG为0 ,说明整个循环没有一个分配方案,输出No Solution,否则输出result中的方案i(女生分配i间,男生n-i间)
具体代码实现部分:
#include<stdio.h>
int main(){
int n0,n1,n;
scanf("%d %d %d",&n0,&n1,&n);
int X=n0,Y=n/2,flag=0,temp=0,com=0,tempcom=1000000000,result=0;//为预防人数差过大,设置tempcom为100000000000保证第一次分配方案被载入tempcom
int FLAG=0;
if(n0>n1){
X=n1;
}
for(int i=2;i<X;i++){
if(i==n){
break;
}
if(n1%(n-i)==0&&n0%i==0){
flag=1;//此次循环是否有分配方案标志
FLAG=1;//是否有分配方案标志
}
if(flag==1){
temp=i;
com=(n-2i)*(n1/(n-i)-n0/i);//计算男女寝室人数差
if(com<0){
com=-com;
}
if(com<tempcom){
tempcom=com;//tempcom存储最少的人数差
result=i;//result存储最少的人数差的时候女生的分配间数i
}
flag=0;
}
}
if(FLAG==0){
printf("No Solution");
}else{
printf("%d %d\n",result,n-result);
}
}
PTA提交结果:
答案正确
总结:多设置标志位和暂存数据的变量可以方便判断是否有结果以及所求方案是否为最佳方案