踩大坑,不要乱用容器,尤其是在时间要求比较严格的题目中

18233 万湖之国的形成

时间限制:2500MS  代码长度限制:10KB

Description

N国原是一块平原上,没有湖,直到一颗小行星撞入大气层碎成成千上万的碎片,碎片再撞击地面形成
一个一个的坑, 下雨之后,最终形成万湖之国。
现在科学家想用计算机模拟万湖之国形成过程,假设每一块碎片撞击地面,都撞出一个园形坑,现在知道
每一个碎片造成的坑的圆心和半径,问每个坑都注满水后,最终形成多少个湖?

输入格式

第一行一个整数N,1<=N<=100,000,表示坑的数量
此后N行,每一行三个double实数,前两个数是圆心的坐标x和y,最后一个数是圆半径(不大于1000)
(数据随机产生,分布均匀)

输出格式

湖的个数

输入样例

3
0 0 5
10 0 5
11.1 0 2.5

输出样例

2

最近在写oj时频繁超时,但是去看别人的题解发现思路和代码几乎一致,那么到底是什么原因导致了超时?于是我逐行逐行检查,最后发现这个锅是vector的

我的代码

#include<iostream>
#include<algorithm>
#include<sstream>
#include<math.h>
#include<vector>
#include<queue>
#include<list>
#include<map>
#include<set>
#include<string>
#include<stdio.h>
#include<ctype.h>
#include<cstring>
#include<cstdlib>
#include<iomanip>
using namespace std;
typedef long long ll;
struct lake
{
	double x, y, r;
	bool operator <(const lake a)const
	{
		return x + r < a.x + a.r;
	}
};
vector<lake>L;
int fa[100005];

int find(int i)
{
	return fa[i] == i ? fa[i] : fa[i] = find(fa[i]);
}
int main()
{
	//freopen("in.txt", "r", stdin);
	ios::sync_with_stdio(0);
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		fa[i] = i;
		lake a;
		cin >> a.x >> a.y >> a.r;
		L.push_back(a);
	}
	sort(L.begin(), L.end());
	ll cnt = n;
	for (int i = 0; i < n; i++)
	{
		for (int j = i-1; j >=0; j--)
		{
			if (L[j].x + L[j].r <= L[i].x - L[i].r)    break;
			if (((L[j].x - L[i].x) * (L[j].x - L[i].x) + (L[j].y - L[i].y) * (L[j].y - L[i].y)) < (L[j].r + L[i].r)* (L[j].r + L[i].r))
			{
				int fai = find(i);
				int faj = find(j);
				if (fai != faj) cnt--;
				fa[fai] = fa[faj];
			}
		}
	}
	cout << cnt;
}

别人未使用vector 的代码

#include <iostream>//!!万湖之国
#include <algorithm>
using namespace std;
int p[100050];
struct circle
{
    double x,y;
    double r;
} c[100050]; //设置成这个大小的原因
bool com(struct circle a,struct circle b)//每个圆右端点的位置大小,给每个圆排序
{
    return a.x+a.r<b.x+b.r ;
}
long long find(int x)
{
    if(p[x]==x) return x;
    else return p[x]=find(p[x]);
}
int main()
{
    long long  n;
    long long count;
    cin >>n;
    count=n;
    for(int i=0; i<n; i++)
    {
        cin>>c[i].x>>c[i].y>>c[i].r;
        p[i]=i;//!!
    }
    sort(c,c+n,com);//!!按照圆的右端点位置排序
    for(int i=0; i<n; i++)
    {
        for(int j=i-1; j>=0; j--)//!!和第i个圆的左边的j个圆比较
        {
            if(c[j].x+c[j].r<=c[i].x-c[i].r) break;//!!第i个圆的左端点横坐标值是否大于前面的第j个圆右端点横坐标值
            if(((c[j].x-c[i].x)*(c[j].x-c[i].x)+(c[j].y-c[i].y)*(c[j].y-c[i].y))<(c[j].r+c[i].r)*(c[j].r+c[i].r))//d<r1+r2
            {
                long long r,l;
                r=find(i);
                l=find(j);
                if(r!=l) count--;//如果两个圆的父结点不同,圆坑数量-1
                p[r]=l;//把两个圆坑合为一个,父节点相同
            }
        }
    }
    cout << count<< endl;
    return 0;
}

 前面代码未优化超时

 后面用vector的ac代码

 用数组代替vector的代码

 

18130 繁忙的公路

时间限制:6000MS  代码长度限制:10KB

Description

在一条笔直的大道(单方向行车道)上,汽车川流不息。道路从起点到终点,等距离的标记了1到N,
即起点是1,然后分别是2、3、4.....,终点是N。每一个标记处,安装了智能探头,可以感知
在该点处车辆的增减数量。
一开始,整条道路上,没有车,然后,是不断接收到的智能探头发回的信息,格式如下:
H 5 9
H表明收到的是智能探头的回传信息,5表示标记5处的车辆信息,9表示该处车辆增加了9辆。
同时,在某个时刻,需要查询在一段连续的道路上,共有多少辆车
查询格式如下:
Q 3 10
Q表明收到的是查询,3是起点,10是终点(包括3和10两处)
要求编程实现正确处理上述信息处理和查询

输入格式

第一行一个整数N(1<=N<=1,000,000),表示标记范围是1到N
第二行一个整数M(1<=M<=100,000),表示探头信息(或查询)的总数量
此后M行,每行一个探头信息或查询请求

输出格式

每逢遇到查询的时候,输出查询范围内的有多少辆车,占一行,查询结果最大不超过2的63次方

输入样例

10
4
H 5 10
Q 1 10
H 6 20
Q 1 10

输出样例

10
30

提示

开始时,整条路上没有车辆

以下两段代码的区别仅仅是有没有使用vector

#include<iostream>
#include<algorithm>
#include<sstream>
#include<math.h>
#include<vector>
#include<queue>
#include<list>
#include<map>
#include<set>
#include<string>
#include<stdio.h>
#include<ctype.h>
#include<cstring>
#include<cstdlib>
#include<iomanip>
using namespace std;
typedef long long ll;
ll N, M;
ll v[1000005];
ll lowbit(ll n)
{
	return -n & n;
}
void add(int local, ll num)
{
	while (local <= N)
	{
		v[local] += num;
		local += lowbit(local);
	}
}

long long sum(int index)
{
	long long sum = 0;
	while (index > 0) {
		sum += v[index];
		index -= lowbit(index);
	}
	return sum;
}
int main()
{
	//freopen("in.txt", "r", stdin);
	ios::sync_with_stdio(0);
	cin >> N;
	cin >> M;
	
	for (int i = 1; i <= M; i++)
	{
		char s;
		ll l, r;
		cin >> s >> l >> r;
		if (s == 'H')
		{

			add(l, r);
		}
		else
		{
			cout << sum(r) - sum(l - 1) << "\n";
		}
	}

}
#include<iostream>
#include<algorithm>
#include<sstream>
#include<math.h>
#include<vector>
#include<queue>
#include<list>
#include<map>
#include<set>
#include<string>
#include<stdio.h>
#include<ctype.h>
#include<cstring>
#include<cstdlib>
#include<iomanip>
using namespace std;
typedef long long ll;
ll N, M;
ll lowbit(ll n)
{
	return -n & n;
}
void add(int local, ll num, vector<ll>& v)
{
	while (local <= N)
	{
		v[local] += num;
		local += lowbit(local);
	}
}

long long sum(int index, vector<ll>v)
{
	long long sum = 0;
	while (index > 0) {
		sum += v[index];
		index -= lowbit(index);
	}
	return sum;
}
int main()
{
	//freopen("in.txt", "r", stdin);
	ios::sync_with_stdio(0);
	cin >> N;
	cin >> M;
	vector<ll>v(N + 1, 0);
	for (int i = 1; i <= M; i++)
	{
		char s;
		ll l, r;
		cin >> s >> l >> r;
		if (s == 'H')
		{

			add(l, r, v);
		}
		else
		{
			cout << sum(r, v) - sum(l - 1, v) << "\n";
		}
	}

}

 这道题的限制时间是6000ms,已经是比较长的了,但是用vector还是超时

 如果大家以后在写时间要求严格的题目时,可以考虑把vector换成普通的数组,可能程序效率会有所提升

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>