双向链表 csu1692 Vector Field
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双向链表 csu1692 Vector Field相关的知识,希望对你有一定的参考价值。
传送门:点击打开链接
题意:有n(<=3000)个位置,位置上有一个加速器,并且表示了方向,当例子通过这个加速器后,运动方向会变成加速器指向的方向,并且速度+1,加速器消失。
问最大能加速多少。
思路:最好的方法就是先离散化一下,然后用双向链表来维护,复杂度能降低到O(n^2)
不过当时太懒了,写了个set,双向链表的写法有空再补,先挖个坑
#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<bitset>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck(x) cout<<"["<<x<<"]"
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
const int MX = 3e3 + 5;
struct Point
int x, y, d; //下左上右
P[MX];
struct Data
int val, id;
Data()
Data(int _id, int _val)
val = _val; id = _id;
bool operator<(const Data &P) const
return val < P.val;
;
set<Data>X[MX], Y[MX];
int tmpX[MX], tmpY[MX];
int solve(int u)
int begin = u;
set<Data>::iterator it;
int ret = 0;
while(true)
ret++;
X[P[u].x].erase(Data(u, P[u].y));
Y[P[u].y].erase(Data(u, P[u].x));
if(P[u].d == 0)
it = X[P[u].x].lower_bound(Data(0, P[u].y));
if(it == X[P[u].x].begin()) return ret;
it--;
if(P[u].d == 1)
it = Y[P[u].y].lower_bound(Data(0, P[u].x));
if(it == Y[P[u].y].begin()) return ret;
it--;
if(P[u].d == 2)
it = X[P[u].x].upper_bound(Data(0, P[u].y));
if(it == X[P[u].x].end()) return ret;
if(P[u].d == 3)
it = Y[P[u].y].upper_bound(Data(0, P[u].x));
if(it == Y[P[u].y].end()) return ret;
//if(begin==5&&P[u].x==2&&P[u].y==1) fuck(P[u].d);
u = it->id;
return ret;
int main()
int n; //FIN;
while(~scanf("%d", &n))
for(int i = 1; i <= n; i++)
char w[10];
scanf("%d%d%s", &P[i].x, &P[i].y, w);
tmpX[i] = P[i].x; tmpY[i] = P[i].y;
if(w[0] == v) P[i].d = 2;
if(w[0] == <) P[i].d = 1;
if(w[0] == ^) P[i].d = 0;
if(w[0] == >) P[i].d = 3;
int sz1, sz2;
sort(tmpX + 1, tmpX + 1 + n);
sort(tmpY + 1, tmpY + 1 + n);
sz1 = unique(tmpX + 1, tmpX + 1 + n) - tmpX - 1;
sz2 = unique(tmpY + 1, tmpY + 1 + n) - tmpY - 1;
for(int i = 1; i <= n; i++)
P[i].x = lower_bound(tmpX + 1, tmpX + 1 + sz1, P[i].x) - tmpX;
P[i].y = lower_bound(tmpY + 1, tmpY + 1 + sz2, P[i].y) - tmpY;
int ans = 0;
for(int u = 1; u <= n; u++)
for(int i = 1; i <= sz1; i++) X[i].clear();
for(int i = 1; i <= sz2; i++) Y[i].clear();
for(int i = 1; i <= n; i++)
X[P[i].x].insert(Data(i, P[i].y));
Y[P[i].y].insert(Data(i, P[i].x));
int t = solve(u);
ans = max(ans, t);
printf("%d\\n", ans);
return 0;
补充:双向链表写法。果然链表比set不止快一点
#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<bitset>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck(x) cout<<"["<<x<<"]"
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
const int MX = 3e3 + 5;
struct Point
int x, y, id;
char d[2];
P[MX];
struct List
int sz, A[MX], WHO[MX];
int L[MX], R[MX], U[MX], D[MX];
int New(int x)
A[x] = ++sz; WHO[sz] = x;
L[sz] = R[sz] = U[sz] = D[sz] = 0;
return sz;
void Delete(int rt)
R[L[rt]] = R[rt];
L[R[rt]] = L[rt];
D[U[rt]] = D[rt];
U[D[rt]] = U[rt];
void Link_x(int u, int v)
R[u] = v; L[v] = u;
void Link_y(int u, int v)
D[u] = v; U[v] = u;
list1, list2;
bool cmp_x(Point a, Point b)
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
bool cmp_y(Point a, Point b)
if(a.y == b.y) return a.x < b.x;
return a.y < b.y;
bool cmp_id(Point a, Point b)
return a.id < b.id;
int solve(int u)
list2 = list1;
int rt = list2.A[u], ret = 0;
while(true)
ret++;
list2.Delete(rt);
if(P[u].d[0] == ^) rt = list2.U[rt];
if(P[u].d[0] == >) rt = list2.R[rt];
if(P[u].d[0] == v) rt = list2.D[rt];
if(P[u].d[0] == <) rt = list2.L[rt];
if(rt == 0) return ret;
u = list2.WHO[rt];
int main()
int n; //FIN;
while(~scanf("%d", &n))
list1.sz = 0;
for(int i = 1; i <= n; i++)
P[i].id = i;
scanf("%d%d%s", &P[i].x, &P[i].y, P[i].d);
list1.New(i);
sort(P + 1, P + 1 + n, cmp_x);
for(int l = 1, r; l <= n; l = r + 1)
for(r = l; r < n && P[l].x == P[r + 1].x; r++);
for(int j = l + 1; j <= r; j++)
list1.Link_y(list1.A[P[j - 1].id], list1.A[P[j].id]);
sort(P + 1, P + 1 + n, cmp_y);
for(int l = 1, r; l <= n; l = r + 1)
for(r = l; r < n && P[l].y == P[r + 1].y; r++);
for(int j = l + 1; j <= r; j++)
list1.Link_x(list1.A[P[j - 1].id], list1.A[P[j].id]);
sort(P + 1, P + 1 + n, cmp_id);
int ans = 0, t;
for(int i = 1; i <= n; i++)
t = solve(i);
ans = max(ans, t);
printf("%d\\n", ans);
return 0;
以上是关于双向链表 csu1692 Vector Field的主要内容,如果未能解决你的问题,请参考以下文章
Java集合 -- ListSetMap三者的区别Arraylist 与 LinkedList 区别RandomAccess接口双向链表和双向循环链表ArrayList 与 Vector