买房与选房
作者:互联网
买房与选房
【问题描述】
在 X 国许多一线城市住房非常紧张,政府部门制定了相关的政策,重点满足住房刚性需求(住房面积为0,社保缴纳必须超过2年),然后才能照顾改善性需求(住房面积大于0)。
具体的原则为:
对于刚性需求,缴纳社保月数多者优先。
对于改善性需求,现有自有住房面积小者优先。
由于房源有限,为公平起见,开发商在不违背上述原则下特意指定同等条件下申报时间同时作为排队的条件,时间越早优先级越高。
最近有一批新楼盘准备开盘,总共有 m (≤1000)套房,所有的网上申报工作都已经完成并保存到二进制文件house.bin中,申请者提交了自己的基本材料,格式为:身份证号(18位,加1位空字符’\0’,共19位)、社保缴纳月数、自有住房面积、申报时间(格式为:MM-DD-YYYY,10位字符串,加1位空字符’\0’,共11位),社保缴纳月数、自有住房面积均为整数,文件最后为总报名人数 n(≤105)。
申请者可以通过身份证号查询最终的结果。
【输入形式】
输入的第一行为两个正整数 m(≤1000)和 T ( T ≤ n ),分别表示本次开盘的楼盘可供申请的套数以及查询的组数。
接下来的 T 行,每行为一个18位的字符串,表示需要查询的身份证号。
【输出形式】
输出为 T 行,对应每个查询的输出结果:
1. 申请者不符合购房条件或排位超出了所推出的房源数量不能中签,则输出"Sorry";
2. 申请者符合购房条件,且该名次人数为1人,则直接输出一个整数,表示选房顺序号;
3. 申请者符合购房条件,且该名次人数有多人,同时人数不大于所剩房源数量,则直接输出用空格分隔的两个整数,表示选房顺序号区间;
4. 申请者符合购房条件,且该名次人数有多人,同时人数大于所剩房源数量,则输出用/分隔两个整数,如 A/B,表示 B 人中选 A 人,选房顺序为排名倒数 A 名范围。
【样例输入】
9 6
350102200609166049
350102200609163286
250342323545313434
130502201805070787
110101196003074525
430102201102181455
【样例输出】
2
3 4
Sorry
6
2/3
Sorry
【测试样例说明】
10%的用例无同等条件的数据,30%的用例只有刚性需求,20%的用例只有改善性需求。
【文件下载】
请下载压缩文件fileDL.zip并在存放源程序文件的文件夹下解开,其中二进制文件house.bin包含了相关的测试数据,test.txt是相关测试数据的文本格式,可用于程序测试。
【题目分析】
1、按照题意,刚需是必须社保时间超过24个月的,也就是>24。
2、如果面积为0,且社保时间<=24个月,是参加改善性住房的资格都没有的;但是如果住房面积大于0对于社保时间是没有要求的,不要问为什么,题目就是这么设定的。
3、判断是否属于同一名次,需要同时考虑申请时间,也就是如果是刚需,则社保时间和申请时间都相同才是同一名次,如果不是刚需,那么住房面积和申请时间都相同才是同一名次。
--罗纲老师
【AC代码】
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
struct people
{
char id[19]; // 身份证号码
int social; // 社保缴纳月数
int area; // 现有住房面积
char date[11]; // 申报日期
// 重载 < 用于排序 (关键)
bool operator<(const people &b) const
{
if (area == 0 && social <= 24)
return 0;
if (b.area == 0 && b.social <= 24)
return 1;
if (area != b.area)
return area < b.area;
if (area == 0 && social != b.social)
return social > b.social;
for (int i = 6; i < 10; ++i)
if (date[i] != b.date[i])
return date[i] < b.date[i];
for (int i = 0; i < 2; ++i)
if (date[i] != b.date[i])
return date[i] < b.date[i];
for (int i = 3; i < 5; ++i)
if (date[i] != b.date[i])
return date[i] < b.date[i];
return 0;
}
};
people *getMess(int &n);
int main()
{
int m, T;
cin >> m >> T;
people *person; // 指向所有报名人的基本资料首地址,通过调用函数getMess获取
int n; // n为报名人数,通过调用函数getMess获取
person = getMess(n);
sort(person, person + n); // 将报名人的资料按要求排序
map<string, int> rank; // 省份证号与排名的键值对
map<int, int> rank_count; // 排名与相同排名的人数的键值对
rank[person[0].id] = 1;
rank_count[rank[person[0].id]] = 1;
for (int i = 0; i < n - 1; i++)
{
if (person[i].area == 0 && person[i].social <= 24)
{
// 不满足刚性需求 排名为-1 相同排名人数为0(不用管)
rank[person[i].id] = -1;
rank_count[rank[person[i].id]] = 0;
}
if (person[i] < person[i + 1])
{
rank[person[i + 1].id] = i + 2;
rank_count[rank[person[i + 1].id]] = 1;
}
else
{
rank[person[i + 1].id] = rank[person[i].id];
rank_count[rank[person[i].id]]++;
}
}
string id;
for (int i = 0; i < T; i++)
{
cin >> id;
// 1. 申请者不符合购房条件或排位超出了所推出的房源数量不能中签,则输出"Sorry"
if (rank[id] > m || rank[id] < 0)
cout << "Sorry" << endl;
else
{
int num = rank_count[rank[id]];
// 2. 申请者符合购房条件,且该名次人数为1人,则直接输出一个整数,表示选房顺序号
if (num == 1)
cout << rank[id] << endl;
// 3. 申请者符合购房条件,且该名次人数有多人,同时人数不大于所剩房源数量,则直接输出用空格分隔的两个整数,表示选房顺序号区间
else if (rank[id] + num - 1 <= m)
cout << rank[id] << " " << rank[id] + num - 1 << endl;
// 4. 申请者符合购房条件,且该名次人数有多人,同时人数大于所剩房源数量,则输出用/分隔两个整数,如 A/B,表示 B 人中选 A 人,选房顺序为排名倒数 A 名范围
else
cout << m - rank[id] + 1 << "/" << num << endl;
}
}
return 0;
}
people *getMess(int &n) /* 将文件数据读入内存 */
{
FILE *fp;
fp = fopen("house.bin", "rb");
fseek(fp, -1 * (long)sizeof(int), 2);
fread(&n, sizeof(int), 1, fp);
rewind(fp);
people *tmp = new people[n];
fread(tmp, sizeof(people), n, fp);
fclose(fp);
return tmp;
}
标签:选房,int,申请者,买房,rank,person,date,id 来源: https://blog.csdn.net/weixin_53524786/article/details/118608260