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换成普通的数组,可能程序效率会有所提升