1095 Cars on Campus(30分)

题目翻译:

给定一系列不同车进校和出校的时间记录,请找出给定时间点校园现存的车以及一天下来在校园中停放最久的车。

题解思路:

思路较为混乱,使用的是暴力(堆shi),有3个小测试点(运行超时)。

1095 Cars on Campus(30分)_第1张图片

可以参考以下优质博客:(采用离线操作)

柳诺大神

一只小毛球

也可参考下边的采用差分思想解决的代码

代码:

差分求解(ACMer室友——pujx,他怎么这么强ಥ﹏ಥ):

#include 
using namespace std;

int n, q;
map>> mp;

int main() {
	cin >> n >> q;

	for (int i = 1; i <= n; i++) {
		int h, m, s; string str, io;
		cin >> str; scanf("%d:%d:%d", &h, &m, &s); cin >> io;
		mp[str].emplace_back(h * 3600 + m * 60 + s, io == "out");
	}

	int mxlen = 0;
	set mx;
	vector a(24 * 60 * 60 + 1);

	for (const auto& [str, v] : mp) {//换名变量用于节约时间
		sort(v.begin(), v.end());//pair重载过<号,第一个是主关键字,第二个是次关键字
		int tot = 0;
		for (int i = 0; i < v.size() - 1; i++)
			if (v[i].second == 0 && v[i + 1].second == 1)
				a[v[i].first]++, a[v[i + 1].first]--, tot += v[i + 1].first - v[i].first;//由原数组得到差分数组
		if (tot == mxlen) mx.insert(str);
		else if (tot > mxlen) mx.clear(), mx.insert(str), mxlen = tot;
	}

	for (int i = 1; i < a.size(); i++) a[i] += a[i - 1];//由差分数组得到目标数组

	while (q--) {
		int h, m, s;
		scanf("%d:%d:%d", &h, &m, &s);
		cout << a[h * 3600 + m * 60 + s] << endl;//对应时刻的值便为当前时刻的校内总车数
	}

	for (auto& str : mx) cout << str << ' ';
	printf("%02d:%02d:%02d\n", mxlen / 3600, mxlen / 60 % 60, mxlen % 60);
}
/*
	 _____   _   _       _  __    __
	|  _  \ | | | |     | | \ \  / /
	| |_| | | | | |     | |  \ \/ /
	|  ___/ | | | |  _  | |   }  {
	| |     | |_| | | |_| |  / /\ \
	|_|     \_____/ \_____/ /_/  \_\
*/

暴力求解(三个测试点未过):

#include
using namespace std;
int N,K;
struct record {
	string Time;
	bool tag;//0进1出
	record(string s1, string s2)
	{
		Time = s1;
		tag = ((s2 == "in") ? 0 : 1);
	}
	const bool operator <(const record& r) const
	{	return Time < r.Time;}
};

int cha(pair p)
{
	int h1 = stoi(p.first.substr(0, 2));
	int m1 = stoi(p.first.substr(3, 2));
	int s1 = stoi(p.first.substr(6, 2));
	int h2 = stoi(p.second.substr(0, 2));
	int m2 = stoi(p.second.substr(3, 2));
	int s2 = stoi(p.second.substr(6, 2));
	return h2 * 3600 + m2 * 60 + s2 - (h1 * 3600 + m1 * 60 + s1);
}

struct car {
	string ID;
	vector> records;
	int sum_time=0;
};
vector C(N);
void change(string ID, vector R)
{
	car c1;
	c1.ID = ID;
	pair temp;
	for (int i = 0;i < R.size() - 1;)
	{
		if (R[i].tag == 0 && R[i + 1].tag == 1)
		{
			temp = make_pair(R[i].Time, R[i + 1].Time);
			c1.records.push_back(temp);
			i += 2;
		}
		else
			i++;
	}
	C.push_back(c1);
}

bool comp1(car c1, car c2)
{
	return c1.sum_time > c2.sum_time;
}

int main()
{
	cin >> N >> K;
	string s1, s2, s3;
	map> message;
	for (int i = 0;i < N;i++)
	{
		cin >> s1 >> s2 >> s3;
		record r(s2, s3);
		message[s1].push_back(r);
	}
	for (auto i=message.begin();i!=message.end();i++)
		sort(i->second.begin(), i->second.end());

	for (auto i : message)
		change(i.first, i.second);

	for (int i = 0;i < K;i++)
	{
		string query;
		cin >> query;
		int curcar = 0;
		for (auto j : C)
			for (auto k : j.records)
			{
				if (query >= k.first && query < k.second)
				{
					curcar++;
					break;
				}
			}
		cout << curcar << endl;
	}

	for (int i = 0;i < C.size();i++)
	{
		for (int j = 0;j < C[i].records.size();j++)
			C[i].sum_time += cha(C[i].records[j]);
	}
	sort(C.begin(), C.end(), comp1);
	vector result;
	result.push_back(C[0].ID);
	for (int i = 1;i < C.size();i++)
	{
		if (C[i].sum_time == C[i - 1].sum_time && C[i].sum_time == C[0].sum_time)
			result.push_back(C[i].ID);
	}
	sort(result.begin(), result.end());
	for (auto i : result)
		cout << i << " ";
	cout << setw(2) << setfill('0') << C[0].sum_time / 3600 << ":"<

坑点:

时间可以全部用秒数来记录,简化查询过程;

可以采用差分,降低时间复杂度

你可能感兴趣的:(算法,c++,开发语言)