中金所技术0922笔试第三题–近月和季月
考试的时候没有做出来,时间短没有理清楚,结束后梳理了一下代码如下,输了几个测试用例是正确的,不知道能不能过,有详细注释,有问题欢迎大家评论指正。
1.代码
#include <iostream>
#include <vector>
#include<string>
#include<set>
#include<sstream>
using namespace std;
vector<int> getdate(int y, int m, int dm) { //求y年m月第dm个月后的年份year和月份month
int thisyear = y + (m + dm) / 12;
if ((m + dm) % 12 == 0) {
thisyear -= 1;
}
int thismonth = (m + dm) % 12 == 0 ? 12 : (m + dm) % 12;
return { thisyear, thismonth };
}
string getresstring(int yy, int mm) { //根据年yy和月mm生成字符串,年份和月份少于两位数时前面补0
string ty = yy < 10 ? "0" + to_string(yy) : to_string(yy);
string tm = mm < 10 ? "0" + to_string(mm) : to_string(mm);
string re = "IZ" + ty + tm;
return re;
}
int main() {
string str,str1;
getline(cin, str);
stringstream ss(str);
vector<int> data;
while (getline(ss, str1, ',')) { //输入按‘,’分词
data.emplace_back(stoi(str1));
}
int m = data[0], n = data[1], year = data[2] / 100, month = data[2] % 100, dis = data[3]; //m:近月数,n:季月数,year:开始年份,month:开始月份, dis:未来月数
set<string> jin, ji; //jin:近月字符串集合, ji:季月字符串集合
vector<string> thisrow;
string lastmonth = ""; //记录上个月的字符串,用于集合删除操作
int ptr = 0;
for (int i = 0; i < dis; i++) { //遍历未来月数dis中的每一月
auto date = getdate(year, month, i);
int thisyear = date[0];
int thismonth = date[1];
thisrow= vector<string>(); //记录该月新增字符串
if (i == 0) { //第一个月直接遍历窗口大小m中的月份
for (int j = 0; j < m; j++) {
auto date1 = getdate(thisyear, thismonth, j);
string re1 = getresstring(date1[0], date1[1]);
thisrow.emplace_back(re1);
jin.insert(re1);
}
}
else { //以后只考虑窗口下一个月份
if (m == 0) continue; //m==0的情况不进入
auto date2= getdate(thisyear, thismonth, m-1);
string re2 = getresstring(date2[0], date2[1]);
if (!jin.count(re2) && !ji.count(re2)) { //如果当前月是新的月份,且不在季月中,则为新增
thisrow.emplace_back(re2);
}
if (ji.count(re2)) { //如果当前月在季月集合中,则将该字符串从季月中删除,改成近月字符串
ji.erase(re2);
}
jin.insert(re2);
jin.erase(lastmonth); //从jin集合中删去上个月的近月字符串
}
lastmonth = getresstring(thisyear, thismonth);
while (ji.size() < n) { //判断当前季月字符串集合大小是否达到n个,如果没有,则需利用ptr往后遍历找到符合情况的季月加入到集合中
auto date3= getdate(year, month, ptr);
ptr++; //ptr为全局变量,表示从开始年份year月份month的第ptr个月后
if (date3[1] != 3 && date3[1] != 6 && date3[1] != 9 && date3[1] != 12) { //不为季月直接不考虑
continue;
}
string strt = getresstring(date3[0], date3[1]);
if (jin.count(strt)) { //已经被标记为近月,也不考虑
continue;
}
ji.insert(strt); //符合条件,为季月,插入到季月集合以及新增
thisrow.emplace_back(strt);
}
for (int i = 0; i < thisrow.size(); i++) { //打印结果
if (i == 0) {
cout << thisrow[i];
}
else {
cout << "," << thisrow[i];
}
}
cout << endl;
}
return 0;
}