双向链表 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

二叉树中某一值的路径之 先序遍历 + 二叉搜索树转化为循环双向链表 之 中序遍历

二叉搜索树与双向链表

4.lists(双向链表)

二叉搜索树转换成双向链表

面试题