CCPC-Wannafly Winter Camp Day1 (Div2, onsite)
Replay
Dup4:
- 要是不挂机,再多仔细想想就好了
- J确实自闭好久,一直在想正确性,最后数据错了,喵喵喵?
- 还是要保证充足的休息啊,中间睡了一小会儿,也不知道睡了多久,醒来他们就又过了一道
- 要发掘题目更多的性质和有用条件啊,算法和数据结构只是工具,不要总想着这是啥题这是啥题,我会不会,其实我啥都不会
X:
- 日常挂机时间久,感觉是个不好的习惯。
- 太久没写了,已经不会算复杂度了, TLE MLE到自闭,转身写了个dp就过了?
- 感觉太容易根据数据想算法了, 自导自演。
- 自导自演,顺便演了16的C,演技拉满
A:机器人
Upsolved.
思路:
考虑两种情况
第一种是$b区没有站点需要经过,并且在a区只有一侧有站点需要经过的话$
我们不需要走一个圈,直接从$s走出去到一个特殊点走回s即可$
还有一种就是走一个矩形
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
int n, r, m, k, s;
vector <int> v[], p; int main()
{
while (scanf("%d%d%d%d%d", &n, &r, &m, &k, &s) != EOF)
{
v[].clear(); v[].clear(); p.clear();
for (int i = , x, y; i <= r; ++i)
{
scanf("%d%d", &x, &y);
v[y].push_back(x);
}
sort(v[].begin(), v[].end());
sort(v[].begin(), v[].end());
for (int i = , x; i <= m; ++i)
{
scanf("%d", &x);
p.push_back(x);
}
p.push_back(); p.push_back(n);
sort(p.begin(), p.end());
p.erase(unique(p.begin(), p.end()), p.end());
int Max = ;
int Min = INF;
if (!v[].empty())
{
Max = max(Max, *v[].rbegin());
Min = min(Min, *v[].begin());
}
if (!v[].empty())
{
Max = max(Max, *v[].rbegin());
Min = min(Min, *v[].begin());
}
int pos_Max = lower_bound(p.begin(), p.end(), Max) - p.begin();
int pos_Min = upper_bound(p.begin(), p.end(), Min) - p.begin() - ;
pos_Max = p[pos_Max];
pos_Min = p[pos_Min];
ll res = INFLL;
// b区不需要经过站点
if (v[].empty())
{
if (Max <= s) pos_Max = s;
if (Min >= s) pos_Min = s;
ll tmp = 2ll * (pos_Max - pos_Min);
res = min(res, tmp);
}
// 走矩形路线
if (!v[].empty())
{
ll tmp = 2ll * (pos_Max - pos_Min);
if (!v[].empty()) tmp += 2ll * k;
if (s < pos_Min)
tmp += 2ll * (pos_Min - s);
if (s > pos_Max)
tmp += 2ll * (s - pos_Max);
res = min(res, tmp);
}
printf("%lld\n", res);
}
return ;
}
B:吃豆豆
Solved.
思路:
$dp[i][j][k]表示在(i, j)位置, 时间为t获得最多的糖果。$
$那么, 很显然有转移方程$
$dp[i][j][k] -> dp[i +1][j][k + 1]$
$dp[i][j][k] -> dp[i - 1][j][k + 1]$
$dp[i][j][k] -> dp[i][j + 1][k + 1]$
$dp[i][j][k] -> dp[i][j - 1][k + 1]$
$dp[i][j][k] -> dp[i][j][k + 1]$
$当时间k\%T[i][j] == 0时, dp[i][j][k]++$
$一共有n*m*c种状态, 复杂度是O(n*m*c)$
$然后我也不知道我为啥写了个滚动数组$
#include<bits/stdc++.h> using namespace std; const int maxn = + ; int n, m, C;
int sx, sy, ex, ey;
int T[maxn][maxn];
int arr[maxn][maxn];
int brr[maxn][maxn]; int main()
{
while(~scanf("%d %d %d", &n, &m, &C))
{
for(int i = ; i <= n; ++i)
{
for(int j = ; j <= m; ++j)
{
scanf("%d", &T[i][j]);
}
}
scanf("%d %d %d %d", &sx, &sy, &ex, &ey);
memset(arr, -, sizeof arr);
arr[sx][sy] = ;
int step = ;
for(step = ; ; step++)
{
for(int i = ; i <= n; ++i)
{
for(int j = ; j <= m; ++j)
{
brr[i][j] = arr[i][j];
}
}
for(int i = ; i <= n; ++i)
{
for(int j = ; j <= m; ++j)
{
if(i - >= ) arr[i][j] = max(arr[i][j], brr[i - ][j]);
if(i + <= n) arr[i][j] = max(arr[i][j], brr[i + ][j]);
if(j - >= ) arr[i][j] = max(arr[i][j], brr[i][j - ]);
if(j + <= m) arr[i][j] = max(arr[i][j], brr[i][j + ]);
if(step % T[i][j] == )
{
if(arr[i][j] >= ) arr[i][j]++;
}
}
}
if(arr[ex][ey] >= C) break;
}
printf("%d\n", step);
}
return ;
}
C:拆拆拆数
Solved.
思路:
对于两个奇数,因为2和任意奇数都是互质的。
所以可以拆成A(2,A-2),B(B-2,2)
当有偶数的时候,假设A是偶数
对于大于4的偶数,一定可以拆成一个奇质数和一个奇数之和,相应的将另一个数拆成一个2对应之前的奇数,剩下的只要做到与奇质数互质即可。
因为3*5*7*11*13*17*19*23*29*31*37*41*43*47*53>1e9,所以B-2在53之前一定有一个奇质数不是B-2的因子。
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll GCD(ll a, ll b)
{
return b == ? a : GCD(b, a % b);
} ll a, b;
ll prime[] = {, , , , , , , , , , , , , , , };// int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%lld %lld", &a, &b);
if(GCD(a, b) == )
{
puts("");
printf("%lld %lld\n", a, b);
continue;
}
if(a == b)
{
if(a & )
{
ll ans1 = a / ;
ll ans2 = a - a / ;
puts("");
printf("%lld %lld\n", ans1, ans2);
printf("%lld %lld\n", ans2, ans1);
}
else
{
ll ans1 = a / - ;
ll ans2 = a - ans1;
puts("");
printf("%lld %lld\n", ans1, ans2);
printf("%lld %lld\n", ans2, ans1);
}
continue;
}
if(a % == && b % == )
{
ll ans1 = , ans2 = a - ;
ll ans3 = b - , ans4 = ;
puts("2\n");
printf("%lld %lld\n", ans1, ans3);
printf("%lld %lld\n", ans2, ans4);
}
else
{
int isswap = ;
if(b % == )
{
swap(a, b);
isswap = ;
}
int flag = ;
ll ans1, ans2, ans3, ans4;
ans3 = b - ;
ans4 = ;
for(int i = ; i <= && prime[i] + <= a; ++i)
{
if((b - ) % prime[i] != )
{
flag = ;
ans1 = prime[i];
ans2 = a - prime[i];
break;
}
}
if(flag)
{
if(isswap)
{
swap(ans1, ans3);
swap(ans2, ans4);
}
puts("");
printf("%lld %lld\n", ans1, ans3);
printf("%lld %lld\n", ans2, ans4);
continue;
}
ans3 = b - b % a - ;
ans4 = b - ans3;
for(int i = ; i <= && prime[i] + <= a; ++i)
{
ans1 = prime[i];
ans2 = a - prime[i];
if(GCD(ans1, ans3) == && GCD(ans2, ans4) == )
{
flag = ;
break;
}
}
if(flag)
{
if(isswap)
{
swap(ans1, ans3);
swap(ans2, ans4);
}
puts("");
printf("%lld %lld\n", ans1, ans3);
printf("%lld %lld\n", ans2, ans4);
}
else
{
puts("-1");
}
}
}
return ;
}
好像直接暴力就行了?
#include <bits/stdc++.h>
using namespace std; #define ll long long
int t; ll a, b; ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
void solve()
{
for (int i = ; i <= min(a, 1ll * ); ++i) for (int j = ; j <= min(b, 1ll * ); ++j) if (gcd(i, j) == && gcd(a - i, b - j) == )
{
puts("");
printf("%d %d\n", i, j);
printf("%lld %lld\n", a - i, b - j);
return;
}
} int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%lld%lld", &a, &b);
if (gcd(a, b) == )
{
puts("");
printf("%lld %lld\n", a, b);
}
else solve();
}
return ;
}
E:流流流动
Upsolved.
这些边连起来会形成一棵树、简单树形dp即可
#include <bits/stdc++.h>
using namespace std; #define N 210
int n, f[N], d[N];
vector <int> G[N]; int pre[N];
int find(int x) { return pre[x] == ? x : pre[x] = find(pre[x]); }
void join(int x, int y)
{
int fx = find(x), fy = find(y);
if (fx != fy)
pre[fx] = fy;
} int dp[N][];
void DFS(int u, int fa)
{
dp[u][] = ;
dp[u][] = f[u];
for (auto v : G[u]) if (v != fa)
{
DFS(v, u);
dp[u][] += max(dp[v][], dp[v][]);
dp[u][] += max(dp[v][], dp[v][] - d[min(u, v)]);
}
} int main()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) G[i].clear();
memset(pre, , sizeof pre);
memset(dp, , sizeof dp);
for (int i = ; i <= n; ++i) scanf("%d", f + i);
for (int i = ; i <= n; ++i) scanf("%d", d + i);
for (int i = ; i <= n; ++i)
{
if (i & )
{
if ( * i + <= n)
{
G[ * i + ].push_back(i);
G[i].push_back( * i + );
join( * i + , i);
}
}
else
{
G[i].push_back(i / );
G[i / ].push_back(i);
join(i, i / );
}
}
for (int i = ; i <= n; ++i) if (!pre[i])
{
G[].push_back(i);
G[i].push_back();
}
DFS(, );
printf("%d\n", max(dp[][], dp[][]));
}
return ;
}
F:爬爬爬山
Solved.
思路:
考虑海拔和体力的关系,即最高可以爬的山为$h[1] + k$
那么对于其他高度不符合的山,我们就需要降低其高度
可以理解为点有点权,边有边权,经过边和点都要加上其权值,求最短路
将一个点拆成两个点,中间连条有向边,权值为该点点权,再跑最短路即可
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 200010
#define INFLL 0x3f3f3f3f3f3f3f3f
int n, m, k, h[N];
ll d;
struct Graph
{
struct node
{
int to, nx; ll w;
node () {}
node (int to, int nx, ll w) : to(to), nx(nx), w(w) {}
}a[N << ];
int head[N], pos;
void init()
{
memset(head, , sizeof head);
pos = ;
}
void add(int u, int v, ll w)
{
a[++pos] = node(v, head[u], w); head[u] = pos;
}
}G;
#define erp(u) for (int it = G.head[u], v = G.a[it].to; it; it = G.a[it].nx, v = G.a[it].to) struct node
{
int to; ll w;
node () {}
node (int to, ll w) : to(to), w(w) {}
bool operator < (const node &other) const { return w > other.w; }
};
ll dist[N]; bool used[N];
void Dijkstra()
{
for (int i = ; i <= * n + ; ++i) dist[i] = INFLL, used[i] = false;
dist[] = ; priority_queue <node> pq; pq.push(node(, ));
while (!pq.empty())
{
int u = pq.top().to; pq.pop();
if (used[u]) continue;
used[u] = true;
erp(u)
{
ll w = G.a[it].w;
if (!used[v] && dist[v] > dist[u] + w)
{
dist[v] = dist[u] + w;
pq.push(node(v, dist[v]));
}
}
}
} int main()
{
while (scanf("%d%d%d", &n, &m, &k) != EOF)
{
G.init();
for (int i = ; i <= n; ++i) scanf("%d", h + i);
d = h[] + k;
for (int i = , u, v, w; i <= m; ++i)
{
scanf("%d%d%d", &u, &v, &w);
G.add( * u + , * v, w);
G.add( * v + , * u, w);
}
for (int i = ; i <= n; ++i)
{
ll w = ;
if (h[i] > d) w = 1ll * (h[i] - d) * (h[i] - d);
G.add( * i, * i + , w);
}
Dijkstra();
printf("%lld\n", dist[ * n + ]);
}
return ;
}
I:起起落落
Upsolved.
思路:
$f[i] 表示以i结尾的方案数$
$f[i] = \sum\limits_{j = 1}^{i - 1} [p[j] > p[i]] \cdot f[j] \cdot \sum\limits_{k = j + 1}^{i - 1} [p[k] < p[i]]$
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 2010
const ll MOD = (ll)1e9 + ;
int n, p[N];
ll f[N]; int main()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d", p + i);
memset(f, , sizeof f);
for (int i = ; i <= n; ++i)
{
int cnt = p[i - ] < p[i];
for (int j = i - ; j >= ; --j)
{
if (p[j] > p[i])
f[i] = (f[i] + (f[j] + ) * cnt % MOD) % MOD;
else
++cnt;
}
}
ll res = ;
for (int i = ; i <= n; ++i) res = (res + f[i]) % MOD;
printf("%lld\n", res);
}
return ;
}
Div1:
用权值线段树来维护这个式子
我们考虑$f[x]的方案只会对 y > x \;并且\; p[y] < p[x] 的y产生贡献$
产生贡献的次数是$z \in [x + 1, y - 1] 中 p[z] < p[x] 的个数$
我们对于$z \in [x + 1, y - 1] 中,不管p[z] 与 p[x] 的大小关系$
全都把次数算上
再考虑删除多算的贡献
对于$z \in [x + 1, y - 1] 它多产生的贡献是 x \in [1, z] \;并且\; p[x] > p[z] 的 f[x] 之和$
$那就是权值线段树上的 区间更新 单点更新 区间查询的操作$
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 100010
const ll MOD = (ll)1e9 + ;
int n, p[N]; void up(ll &x) { if (x >= MOD) x -= MOD; }
namespace SEG
{
struct node
{
ll base, v, lazy;
node () {}
node (ll base, ll v, ll lazy) : base(base), v(v), lazy(lazy) {}
void init() { base = v = lazy = ; }
node operator + (const node &other) const
{
node res; res.init();
res.base = (base + other.base) % MOD;
res.v = (v + other.v) % MOD;
return res;
}
}a[N << ], res;
void init() { memset(a, , sizeof a); }
void pushdown(int id)
{
if (!a[id].lazy) return;
up(a[id << ].lazy += a[id].lazy);
up(a[id << | ].lazy += a[id].lazy);
a[id << ].v = (a[id << ].v + a[id].lazy * a[id << ].base % MOD) % MOD;
a[id << | ].v = (a[id << | ].v + a[id].lazy * a[id << | ].base % MOD) % MOD;
a[id].lazy = ;
}
void update(int id, int l, int r, int ql, int qr, ll v)
{
if (l >= ql && r <= qr)
{
up(a[id].lazy += v);
a[id].v = (a[id].v + a[id].base * v % MOD) % MOD;
return;
}
int mid = (l + r) >> ;
pushdown(id);
if (ql <= mid) update(id << , l, mid, ql, qr, v);
if (qr > mid) update(id << | , mid + , r, ql, qr, v);
a[id] = a[id << ] + a[id << | ];
}
void update2(int id, int l, int r, int pos, ll base, ll v)
{
if (l == r)
{
up(a[id].base += base);
up(a[id].v += v);
return;
}
int mid = (l + r) >> ;
pushdown(id);
if (pos <= mid) update2(id << , l, mid, pos, base, v);
else update2(id << | , mid + , r, pos, base, v);
a[id] = a[id << ] + a[id << | ];
}
void query(int id, int l, int r, int ql, int qr)
{
if (l >= ql && r <= qr)
{
res = res + a[id];
return;
}
int mid = (l + r) >> ;
pushdown(id);
if (ql <= mid) query(id << , l, mid, ql, qr);
if (qr > mid) query(id << | , mid + , r, ql, qr);
}
} int main()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) scanf("%d", p + i);
SEG::init();
ll res = ;
for (int i = ; i <= n; ++i)
{
SEG::res.init();
SEG::query(, , n, p[i] + , n);
up(res += SEG::res.v);
SEG::update(, , n, p[i] + , n, );
SEG::update2(, , n, p[i], SEG::res.v + , (-SEG::res.base + MOD) % MOD);
}
printf("%lld\n", res);
}
return ;
}
J:夺宝奇兵
Solved.
思路:
考虑居民拥有的最大宝物数为$m$
可以枚举这个值,贪心$check()$即可
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 1010
int n, m;
vector <int> v[N]; ll check(int x)
{
ll res = ;
int cnt = ;
priority_queue <int, vector <int>, greater <int> > q;
for (int i = ; i <= n; ++i)
{
int need = v[i].size() - x;
for (auto it : v[i])
{
if (need > )
{
--need;
res += it;
++cnt;
}
else
q.push(it);
}
}
while (cnt <= x)
{
++cnt;
res += q.top(); q.pop();
}
return res;
} int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = ; i <= n; ++i) v[i].clear();
for (int i = , a, c; i <= m; ++i)
{
scanf("%d%d", &a, &c);
v[c].push_back(a);
}
for (int i = ; i <= n; ++i) sort(v[i].begin(), v[i].end());
ll res = (ll)1e18;
for (int i = ; i < m; ++i)
res = min(res, check(i));
printf("%lld\n", res);
}
return ;
}
Div1:
从大到小枚举$x$, 发现在大的$x的情况下会买掉的,在小的x下一定会买掉$
$每件物品最多操作一次,再用线段树维护前k小之和即可$
复杂度$O(nlogn)$
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 100010
#define pii pair <int, int>
int n, m;
struct node
{
int a, c;
void scan() { scanf("%d%d", &a, &c); }
bool operator < (const node &other) const { return a < other.a; }
}arr[N];
queue <pii> q[N];
vector <int> vec[N]; namespace SEG
{
ll v[N << ]; int cnt[N << ];
void pushup(int id) { v[id] = v[id << ] + v[id << | ]; cnt[id] = cnt[id << ] + cnt[id << | ]; }
void build(int id, int l, int r)
{
v[id] = ; cnt[id] = ;
if (l == r)
{
v[id] = arr[l].a;
cnt[id] = ;
return;
}
int mid = (l + r) >> ;
build(id << , l, mid);
build(id << | , mid + , r);
pushup(id);
}
void update(int id, int l, int r, int pos)
{
if (l == r)
{
v[id] = ;
cnt[id] = ;
return;
}
int mid = (l + r) >> ;
if (pos <= mid) update(id << , l, mid, pos);
else update(id << | , mid + , r, pos);
pushup(id);
}
ll query(int id, int l, int r, int k)
{
if (k <= ) return ;
if (k == cnt[id]) return v[id];
int mid = (l + r) >> ;
ll res = ;
res += query(id << , l, mid, min(k, cnt[id << ]));
if (k - cnt[id << ] > ) res += query(id << | , mid + , r, k - cnt[id << ]);
return res;
}
} ll tmp;
int cnt;
void work(int x)
{
if (x - ) for (auto it : vec[x]) vec[x - ].push_back(it);
for (auto it : vec[x])
{
pii top = q[it].front(); q[it].pop();
++cnt;
tmp += top.first;
SEG::update(, , m, top.second);
}
} int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = ; i <= m; ++i) arr[i].scan();
sort(arr + , arr + + m);
for (int i = ; i <= m; ++i) q[arr[i].c].push(pii(arr[i].a, i));
SEG::build(, , m);
for (int i = ; i <= n; ++i) vec[q[i].size()].push_back(i);
ll res = (ll)1e18; tmp = ; cnt = ;
if (!vec[m].empty())
{
++cnt;
int it = *vec[m].begin();
pii top = q[it].front(); q[it].pop();
vec[m - ].push_back(it);
tmp += top.first;
SEG::update(, , m, top.second);
}
for (int i = m - ; i >= ; --i)
{
work(i);
res = min(res, tmp + SEG::query(, , m, i - cnt));
}
printf("%lld\n", res);
}
return ;
}
CCPC-Wannafly Winter Camp Day1 (Div2, onsite)的更多相关文章
- 2020 CCPC Wannafly Winter Camp Day1 C. 染色图
2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...
- 2019 CCPC-Wannafly Winter Camp Day1 (Div2, onsite)
solve:4/11 补题:6/11 A 机器人 补题:zz 这是一道分类讨论的题目,有一个规律就是如果必须要从第一个区到第二个区,那么最多转区两次(1到2一次,2到1一次),然后分类讨论即可,只要细 ...
- CCPC-Wannafly Winter Camp Day1 (Div2, onsite) A B C E F I J
A 机器人 链接:https://www.cometoj.com/contest/7/problem/A?problem_id=92 思路: 分两大类讨论: 1. B区没有点: (1)点都在起点左边 ...
- CCPC-Wannafly Winter Camp Day1 (Div2, onsite) - I 起起落落
题目描述 无聊的wlswls正在观察某个商品的价格,wlswls一共观察了nn天,每天这个商品都会有一个价格p_ipi. 定义一个长度为2m+1(3\leq2m+1\leq n)2m+1(3≤2m+ ...
- CCPC-Wannafly Winter Camp Day1 (Div2, onsite) 夺宝奇兵
题目描述 wlswls所在的王国有nn个居民(不包括wlswls),他们共有mm件神奇的宝物. 对于第ii件宝物,wlswls可以花费a_iai的金币把它从原来的主人那里买过来. 请问wlswls最 ...
- 2020 CCPC Wannafly Winter Camp Day1 Div.1& F
#include<bits/stdc++.h> #define forn(i, n) for (int i = 0; i < int(n); i++) #define fore(i, ...
- 2020 CCPC Wannafly Winter Camp Day1 - I. K小数查询(分块)
题目链接:K小数查询 题意:给你一个长度为$n$序列$A$,有$m$个操作,操作分为两种: 输入$x,y,c$,表示对$i\in[x,y] $,令$A_{i}=min(A_{i},c)$ 输入$x,y ...
- CCPC-Wannafly Winter Camp Day1 (Div2 ABCFJ) 待补...
Day1 Div2 场外链接 按题目顺序~ A 机器人 传送门 题意:有两条平行直线A.B,每条直线上有n个点,编号为1~n.在同一直线上,从a站点到b站点耗时为两点间的距离.存在m个特殊站点,只有在 ...
- CCPC Wannafly Winter Camp Div2 部分题解
Day 1, Div 2, Prob. B - 吃豆豆 题目大意 wls有一个\(n\)行\(m\)列的棋盘,对于第\(i\)行第\(j\)列的格子,每过\(T[i][j]\)秒会在上面出现一个糖果, ...
随机推荐
- android素材资源
这里先给大家 推荐两个 找图标的 搜索引擎 http://findicons.com/ 这个我也在用 大家也可以试试 找个图标还是很easy的. http://www.iconfinder. ...
- linux解压和压缩
1.压缩命令: 命令格式:tar -zcvf 压缩文件名.tar.gz 被压缩文件名 可先切换到当前目录下.压缩文件名和被压缩文件名都可加入路径. 2.解压缩命令: 命令格式:tar -z ...
- android studio如何生成签名文件,以及SHA1和MD5值
一.生成签名文件 1.点击菜单栏中的Build的. 2.弹出窗体,如下图,选中Generate Signed APK,并点击. 3.弹出窗体,如下图. 4.点击Create new…按钮,创建一个签名 ...
- JavaScript的记忆函数真的可以提升性能吗?
1 记忆函数是什么呢? 让函数记住曾经计算过的参数对应的结果 2 那我们为什么使用记忆函数呢? 答案是 避免重复计算 3 在工作中如何使用和实现函数记忆 ? 形成闭包,在闭包中维护一个哈希数组(其 ...
- <转>KMP算法详解
看了好久的KMP算法,都一直没有看明白,直到看到了这篇博客http://www.tuicool.com/articles/e2Qbyyf让我瞬间顿悟. 如果你看不懂 KMP 算法,那就看一看这篇文章 ...
- postgresql----LIKE和SIMILAR TO
LIKE和SIMILAR TO都支持模糊查询,另外SIMILAR TO还支持正则表达式查询.模糊查询中有两个重要的符号:下划线'_'匹配任意单个字符,百分号'%'匹配任意多个字符,可以是0个,如果想匹 ...
- 【css预处理器】------sass的基本语法------【巷子】
001.安装sass 1.删除gem源:gem sources --remove https://rubygems.org/ 2.添加国内源:gem sources -a http://gems.ru ...
- Android官方架构组件介绍之LiveData
LiveData LiveData是一个用于持有数据并支持数据可被监听(观察).和传统的观察者模式中的被观察者不一样,LiveData是一个生命周期感知组件,因此观察者可以指定某一个LifeCycle ...
- 解决Ubuntu14.04下vi编辑器不能使用方向键和退格键问题
参考:http://blog.sina.com.cn/s/blog_7d0c2fed01010zbi.html 系统:Ubuntu14.04 使用vi命令时,不能正常编辑文件,使用方向键时老是出现很多 ...
- tooltip提示文字
<p class="tooltip-demo">Tigh <a title="Default tooltip" rel="toolt ...