Hydra

Hydra blog


  • 首页

  • 归档

lc-day20

发表于 2021-12-11

748. 最短补全词

题目

简单签到题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Solution {
public:
string shortestCompletingWord(string licensePlate, vector<string>& words) {
unordered_map<char, int> p;
for(int i = 0; i < licensePlate.size(); i++){
if(licensePlate[i] == ' ') continue;
if(licensePlate[i] >= '0' && licensePlate[i] <= '9') continue;
p[tolower(licensePlate[i])]++;
}
int idx = -1, len = 1010;
for(int i = 0; i < words.size(); i++){
unordered_map<char, int> pp;
for(auto c : words[i]){
pp[c]++;
}
bool flag = false;
for(auto &[c, n] : p){
if(n > pp[c]) {
flag = true;
break;
}
}
if(!flag) {
if(len > words[i].size()) {
len = words[i].size();
idx = i;
}
}
}
return words[idx];
}
};

js版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* @param {string} licensePlate
* @param {string[]} words
* @return {string}
*/
var shortestCompletingWord = function(licensePlate, words) {
const p = new Array(26).fill(0);
for(const ch of licensePlate){
if(/^[a-zA-Z]+$/.test(ch)){
p[ch.toLowerCase().charCodeAt() - 'a'.charCodeAt()]++;
}
}
let idx = -1;
for(let i = 0; i < words.length; i++){
const c = new Array(26).fill(0);
for(let j = 0; j < words[i].length; j++){
const ch = words[i][j];
c[ch.toLowerCase().charCodeAt() - 'a'.charCodeAt()]++;
}
let ok = true;
for(let j = 0; j < 26; j++){
if(c[j] < p[j]) {
ok = false;
break;
}
}
if(ok && (idx < 0 || words[i].length < words[idx].length))
idx = i;
}
return words[idx];
};

714. 买卖股票的最佳时机含手续费

题目

为什么要minprice-fee 当我买完一次股票后, 如果它紧接着又上涨了, 那后面就不用出手续费了, 直到这个上涨区间断掉, 手续费只用扣掉一次, 这样就形成了局部最优解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int result = 0;
int minprice = prices[0];
for(int i = 1; i < prices.size(); i++){
//新的买入, 实际操作就是存储这个最低价格,
//并没有真正的
if(prices[i] < minprice) minprice = prices[i];

//亏本价, 继续持有
if(prices[i] > minprice && prices[i] <= minprice + fee)
continue;

//如果大于最大价+手续费, 买入并且将minprice-fee
if(prices[i] > minprice + fee) {
result += prices[i] - minprice - fee;
minprice = prices[i] - fee;
}
}
return result;
}
};

lc-day19

发表于 2021-12-08

763.划分字⺟区间

题目

思路是找到之前出现的最大下标和,如果当前下标与它相等,就存入答案数组中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* @param {string} s
* @return {number[]}
*/
var partitionLabels = function(s) {
let ans = [];
let nums = new Array(26);
const A = 'a'.charCodeAt(0);
for(let i = 0; i < s.length; i++){
nums[s.charCodeAt(i) - A] = i;
}
let maxx = -1;
for(let i = 0, j = 0; i < s.length; i++){
if(maxx < nums[s.charCodeAt(i) - A]) maxx = nums[s.charCodeAt(i) - A];
if(i == maxx) {
ans.push(i - j + 1);
j = i + 1;
}
}
return ans;
};

合并区间

题目

排序左区间, 然后比较右区间判断是否进行合并, 跟之前的弓箭射气球一题还是有区别的, 后面可以稍微总结一下

我不应该执着于用双指针解题, 研究了一下正确答案发现双指针不能确保第二个慢指针一直指向res的最后一个数组, j是随着i更新, 而不是res末尾

弓箭射气球题要求的是区间数量, 所以可以用右区间排序, 找右区间的交叉点贪心解决, 这题要合并区间就要左右端点同时考虑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public:
static bool cmp(const vector<int>& a, const vector<int>& b){
return a[0] < b[0];
}
vector<vector<int>> merge(vector<vector<int>>& intervals) {
vector<vector<int>> res;
if(intervals.size() == 0) return intervals;
sort(intervals.begin(), intervals.end(), cmp);

res.push_back(intervals[0]);
for(int i = 1; i < intervals.size(); i++){
if(res.back()[1] >= intervals[i][0]) {
res.back()[1] = max(res.back()[1], intervals[i][1]);
}
else {
res.push_back(intervals[i]);
}
}
return res;
}
};

附上js版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* @param {number[][]} intervals
* @return {number[][]}
*/
var merge = function(intervals) {
if(intervals.length === 0) return intervals;
intervals.sort((a, b) => a[0] - b[0]);
let result = [];
result.push(intervals[0]);
for(let i = 1; i < intervals.length; i++){
if(result[result.length - 1][1] < intervals[i][0]) {
result.push(intervals[i]);
}
else {
result[result.length - 1][1] = Math.max(
result[result.length - 1][1],
intervals[i][1]);
}
}
return result;
};

用最少数量的箭引爆气球

题目

不断更新最大maxL, 每更新一次, 答案+1, 第一次更新是因为区间最少有一个, 再者这个循环比了n-1次, 最坏情况下我需要n支弓箭才行,所以+ 1

这题贪心在只要有两个以上的气球重叠, 就射爆它, 不用再考虑后面的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* @param {number[][]} points
* @return {number}
*/
var findMinArrowShots = function(points) {
if(points.length == 0) return 0;

points.sort((a, b) => a[1] - b[1]);
let cnt = 1;
let maxL = points[0][1];
for(let i = 1; i < points.length; i++){
if(maxL < points[i][0]){
cnt++;
maxL = points[i][1];
}

}
return cnt;
};

无重叠区间

题目

和上一题很相似,但是这题用了双指针

这题要考虑最后上一个区间对下一个的交叉情况, 并不断更新两个指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* @param {number[][]} intervals
* @return {number}
*/
var eraseOverlapIntervals = function(intervals) {
if(intervals.length === 0) return 0;
intervals.sort((a, b) => a[1] - b[1]);
let ans = 0 ;
for(let i = 1, j = 0; i < intervals.length; i++){
if(intervals[j][1] > intervals[i][0]) ans++;
else j = i;
}
return ans;
};

蓝桥杯06

发表于 2021-12-03

日志统计

题目

题目

双指针+piar,技巧性题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e6 + 10;
typedef pair<int, int> PII;

PII logs[N]; //统计日志
int cnt[N], st[N]; // cnt是点赞数统计
// st是满足要求的id数

int main(){
int n, limit, k;
scanf("%d%d%d", &n, &limit, &k);
for(int i = 0; i < n; i++){
scanf("%d%d", &logs[i].first, &logs[i].second);
}
sort(logs, logs + n);
for(int i = 0, j = 0; i < n; i++){
int id = logs[i].second;
cnt[id]++;
while(logs[i].first - logs[j].first >= limit){
cnt[logs[j].second]--;
j++;
}
if(cnt[id] >= k) st[id] = 1;
}

for(int i = 0; i <= 1e6; i++){
if(st[i] == 1) printf("%d\n", i);
}
return 0;
}

献给阿尔吉侬的花束

题目

题目

#define 命令是 C 语言中的一个宏定义命令 ,它用来将一个标识符定义为一个字符串

typedef 关键字来定义自己习惯的数据类型名称,来替代系统默认的基本类型名称、数组类型名称,后面有省略号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int N = 210;
int n, m;
char grid[N][N];
int dist[N][N];
int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};

#define x first
#define y second

int bfs(pair<int, int> start, pair<int, int> end){
memset(dist, -1, sizeof dist);
queue<pair<int, int>> q;

dist[start.x][start.y] = 0;
q.push(start);

while(q.size()){
auto t = q.front();
q.pop();

for(int i = 0; i < 4; i++){
int x = t.x + dx[i], y = t.y + dy[i];
if(x < 0 || x >= n || y < 0 || y >= m) continue;
if(grid[x][y] == '#') continue;
if(dist[x][y] != -1) continue;

dist[x][y] = dist[t.x][t.y] + 1;

if(end == make_pair(x, y)) return dist[x][y];
q.push({x, y});
}
}
return -1;
}

int main(){
int T;
cin >> T;
while(T--){
cin >> n >> m;
pair<int, int> start, end;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> grid[i][j];
if(grid[i][j] == 'S') {
start = {i, j};
}
if(grid[i][j] == 'E') end = {i, j};
}
}
int distance = bfs(start, end);
if(distance == -1) puts("oop!");
else cout << distance << endl;
}
return 0;
}

红与黑

题目

题目

对于bfs搜索,要特别注意标记数组标记的位置,遵循开始点在哪赋值,后面就在哪赋值

比如这题。开始点在while循环之前就标记好了,然后再开始队列循环。同理,对于后面的点,也应该是先标记后从队列中取出来操作,所以就是在for循环中标记

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int N = 25;
char grid[N][N];
int st[N][N];
int n, m;
#define x first
#define y second
typedef pair<int, int> PII;
PII start;
int res;

void bfs(){
memset(st, -1, sizeof st);
res = 0;
queue<PII> q;
q.push(start);
st[start.x][start.y] = 0;
int dx[4] = {1, -1, 0, 0}, dy[4] = {0, 0, 1, -1};
while(q.size()){
auto t = q.front();
q.pop();

res++;
for(int i = 0; i < 4; i++){
int x = t.x + dx[i], y = t.y + dy[i];
if(x < 0 || x >= n || y < 0 || y >= m) continue;
if(grid[x][y] == '#') continue;
if(st[x][y] == 0) continue;
st[x][y] = 0;
q.push({x, y});

}
}
}

int main(){
while(cin >> m >> n, m || n){
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> grid[i][j];
if(grid[i][j] == '@') start = {i, j};
}
}
bfs();
cout << res << endl;
}

return 0;
}

交换瓶子

题目

题目

暴力法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<iostream>
using namespace std;
const int N = 10010;
int a[N];

int main(){
int n , m;
cin >> n;
for(int i = 0; i < n; i++){
cin >> a[i];
}
int ans = 0;
for(int i = 0; i < n; i++){
if(a[i] == i + 1) continue;
for(int j = i + 1; j < n; j++){
if(a[j] == i + 1) {
ans ++;
swap(a[j], a[i]);
}
}
}
printf("%d", ans);
return 0;
}

这个题目很经典,建议深刻记忆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<iostream>
using namespace std;
const int N = 10010;
int a[N];
int b[N] = {0};

int main(){
int n;
cin >> n;
for(int i = 1; i <= n; i++){
cin >> a[i];
}
int cnt = 0;
for(int i = 1; i <= n; i++){
if(b[i] == false){ //如果这个点没有环, 就从它开始遍历, 并且此时环数+1
cnt++;
for(int j = i; !b[j]; j = a[j]) b[j] = true; //从这个点的本来的位置出发,连成一个环
}
}
printf("%d", n - cnt);
return 0;
}

lc-day18

发表于 2021-12-03

K 次取反后最大化的数组和

题目

每日一题,贪心题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var largestSumAfterKNegations = function(nums, k) {
let num = nums;
nums.sort(function(a, b){
return Math.abs(a) - Math.abs(b);
})

for(let i = nums.length - 1; i >= 0; i--){
if(nums[i] < 0 && k > 0){
k--;
nums[i] = -nums[i];
}
}

let ans = 0;
for(let i = 0; i < nums.length; i++) ans += nums[i];
if(k % 2 == 0) return ans;
else return ans - 2 * nums[0];
};

lc-day17

发表于 2021-12-02

重刷leetcode的题,不定期更新(改用javascript刷题)

使用最小花费爬楼梯

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* @param {number[]} cost
* @return {number}
*/
var minCostClimbingStairs = function(cost) {
if(cost.length == 2) return Math.min(cost[0], cost[1]);
let arr = [];
arr[0] = cost[0];
arr[1] = cost[1];
for(let i = 2; i < cost.length; i++){
arr[i] = Math.min(arr[i - 1], arr[i - 2]) + cost[i];
}
return Math.min(arr[arr.length - 1], arr[arr.length - 2]);
};

写下面这题之前要搞清楚js中的二维数组如何定义

方法一:传统的定义方式

1
2
3
4
5
6
7
//定义m行n列的数组,初始化为0
let m = 5;
let n = 4;
let arr = new Array(m);
for(let i = 0; i < n; i++){
arr[i] = new Array(n);
}

方法二:奇淫技巧

1
2
3
4
//定义m行n列的数组,初始化为0
let m = 5;
let n = 4;
const arr = new Array(m).fill(0).map(() => new Array(n).fill(0));

不同路径

题目

明天更

sstream

发表于 2021-12-02

stringstream

1.库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本。
使用string对象来代替字符数组。这样可以避免缓冲区溢出的危险。而且,传入参数和目标对象的类型被自动推导出来,即使使用了不正确的格式化符也没有危险。

推荐使用stringstream

string到int的转换

1
2
3
4
string result= ”10000”;
int n = 0;
stream << result;
stream >> n;//n等于10000

如果你打算在多次转换中使用同一个stringstream对象,记住再每次转换前要使用clear()方法;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <sstream>
#include <iostream>
int main()
{
std::stringstream stream;
int first, second;
stream<< "456"; //插入字符串
stream >> first; //转换成int
std::cout << first << std::endl;
stream.clear(); //在进行多次转换前,必须清除stream
stream << true; //插入bool值
stream >> second; //提取出int
std::cout << second << std::endl;
}
1
456 1

蓝桥杯05

发表于 2021-12-02

特别数的和

简单模拟, 今日打卡第一题

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<iostream>
using namespace std;
int main(){
int n, ans = 0;
cin >> n;
for(int i = 1; i <= n; i++){
int num = i;
while(num != 0){
int temp = num % 10;
if(temp == 2 || temp == 1 || temp == 0 || temp == 9) {
ans += i;
break;
}
num /= 10;
}
}
cout << ans << endl;
return 0;
}

错误票据

题目

题目

题目本身没有难度,就是考的输入

借这里强调一下scanf吧,scanf会留下回车,scanf的结束符在键盘上是【ctrl+z】,在文本中是EOF【END OF FILE】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<iostream>
#include<algorithm>
using namespace std;
int a[100010];

int main(){
int n;
scanf("%d", &n);
int mi = 110, ma = -1;
while(scanf("%d", &n) != EOF){
a[n]++;
mi = min(mi, n);
ma = max(ma, n);
}
int cut, wro;
for(int i = mi; i <= ma; i++){
if(a[i] == 2) wro = i;
if(a[i] == 0) cut = i;
}
cout << cut << ' ' << wro << endl;
return 0;
}

yxc的代码用的sstream流,太神奇了

要强调几点

cin的结束符是回车,读取结束后回车仍然会保留在缓冲区中,会让下次的输入继续读取,如果还是cin,那就再留到下一次,空格是不会处理的,scanf同理

getline则是先读取一行,如果碰到回车就会结束,但不会进入缓冲区。所以就可以用getline单独处理cin留下的空格

1
2
cin >> x;			//用x保存输入内容,并留下回车
getline(cin, s); //用s吸收掉回车

stringstream用于分割被空格,制表符号分割的字符串

1
2
3
4
5
6
7
8
9
10
11
12
#include<iostream>  
#include<sstream> //istringstream 必须包含这个头文件
#include<string>
using namespace std;
int main(){
string str="i am a boy";
istringstream is(str);
string s;
while(is>>s) {
cout<<s<<endl;
}
}
1
2
3
4
i
am
a
boy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10010;
int n;
int a[N];
int main()
{
int cnt;
cin >> cnt;
string line;

getline(cin, line); // 忽略掉第一行的回车(getline能吸收回车并删除di)
while (cnt -- )
{
getline(cin, line);
stringstream ssin(line);
while (ssin >> a[n]) n ++ ; //从0开始分割字符串并赋值
}
sort(a, a + n);
int res1, res2;
for (int i = 1; i < n; i ++ )
if (a[i] == a[i - 1]) res2 = a[i]; // 重号
else if (a[i] >= a[i - 1] + 2) res1 = a[i] - 1; // 断号

cout << res1 << ' ' << res2 << endl;
return 0;
}

蓝桥杯04

发表于 2021-12-01

连号区间数

题目

题目

模拟题,虽然简单,但是题目看了半天,宛如智障

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<iostream>
#include<vector>
using namespace std;
const int N = 10010;
int n;
int a[N];

int main(){
cin >> n;

for(int i = 0; i < n; i++){
scanf("%d", &a[i]);
}
int res = 0;
for(int i = 0; i < n; i++){
int max_val, min_val;
for(int j = i; j < n; j++){
if(i == j) {
max_val = a[j];
min_val = a[j];
res ++;
}
else {
max_val = max(max_val, a[j]);
min_val = min(min_val, a[j]);
if(max_val - min_val + 1 == j - i + 1) res ++;
}
}
}
cout << res << endl;

return 0;
}

第 N 位数字

题目

首先找规律,然后进行模拟

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public:
int findNthDigit(int n) {
long long k = 1, x = 9, s = 1;
// k是数的位数, x是这一位数有多少个数, s是这一位数开始的数
while(n > k * x){
n -= k * x;
k++, x *= 10, s *= 10;
}
int key = s + (n - 1) / k; //求出具体是哪一位数, 转换为字符串处理
return to_string(key)[(n - 1) % k] - '0';
}
};

二分法

关于二分法,一般是确定想找的条件,然后再举出它的相反的条件(比如求大于等于target的第一个数,就举出小于target的式子,然后破坏它)

看下面一段代码

1
2
3
4
5
while(l < r){	//l是区间的左端点, r是右端点, 都是能取得到的左闭右闭区间【l,r】
int mid = (l + r) >> 1;
if(a[mid] < target) l = mid + 1; //选择相反的条件, 然后给左端点值赋值破坏这个条件(mid不符合条件,换成mid+1)
else if(a[mid] >= target) r = mid; //下面这一步就不用破坏了, 而是延续这个条件, 这就是二分法
}

递增三元组

菜到令人发指的地步, 写了半天二分,结果发现原来是二分思路的问题,不是我的问题,lower_bound函数在失败时会返回last,而我手写的二分没有这个功能,误入歧途了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include<iostream>
#include<algorithm>
using namespace std;

const int N = 100010;
int a[N], b[N], c[N];


int main(){
int n;
cin >> n;
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i = 1; i <= n; i++) scanf("%d", &b[i]);
for(int i = 1; i <= n; i++) scanf("%d", &c[i]);
sort(a + 1, a + n + 1);
sort(b + 1, b + n + 1);
sort(c + 1, c + n + 1);
long long res = 0;
for(int i = 1; i <= n; i++){
int pos1, pos3;
//第一次查找小于b[i]的第一个数
int l = 1, r = n;
while(l < r){
int mid = (l + r + 1) / 2;
if(b[i] <= a[mid]) r = mid - 1;
else l = mid;
}
pos1 = l;

l = 1, r = n;
//第二次查找大于b[i]的第一个数
while(l < r){
int mid = (l + r) / 2;
if(c[mid] <= b[i]) l = mid + 1;
else r = mid;
}

pos3 = l;

if(a[pos1] < b[i] && b[i] < c[pos3])
res += (long long)pos1 * (n - pos3 + 1);
//cout << pos1 - 1 << ' ' << n - pos3 + 1 << endl;
}
cout << res << endl;
}

经过这么一遭,算是加深二分的印象了,想要求什么就直接二分什么,不要曲线救国

蓝桥杯03

发表于 2021-11-29

买不到的数目

题目

简单dp题,有一点细节要注意

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e6 + 110;
int dp[N];
int main(){
int n, m;
cin >> n >> m;
dp[0] = 1;
if(n > m) swap(n, m);
int ans = 0;
for(int i = n; i < n * m; i++){
if(dp[i - n] || (i >= m && dp[i - m])){
dp[i] = true;
}
else ans = i;
}
cout << ans << endl;
return 0;
}

饮料换购

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<iostream>
using namespace std;

int main(){
int n;
cin >> n;
int ans = n;
while(n >= 3){
n -= 3;
n += 1;
ans++;
}
cout << ans << endl;
return 0;
}

摘花生

题目

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<iostream>
using namespace std;
const int N = 110;

int a[N][N];

int main(){
int T;
cin >> T;
while(T--){
int r, c;
cin >> r >> c;
for(int i = 1; i <= r; i++){
for(int j = 1; j <= c; j++){
cin >> a[i][j];
}
}
for(int i = 1; i <= r; i++){
for(int j = 1; j <= c; j++){
a[i][j] += max(a[i - 1][j], a[i][j - 1]);
}
}
cout << a[r][c] << endl;
}
return 0;
}

最长上升子序列

题目

一段时间不写动态规划, 跟个傻子一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<iostream>
#include<algorithm>
using namespace std;

const int N = 10000;
int a[N];
vector<int> dp(N, 1);//首先将数组初始化为1, 表示最小长度为1
int main(){
int n;
cin >> n;
int ans = 0;

for(int i = 0; i < n; i++) {
cin >> a[i];
}
for(int i = 1; i < n; i++){
for(int j = 0; j <= i - 1; j++){
//固定右端点, 比较左边每一个数, 遍历出dp[i]的max值
// i大于j的值就更新一下
if(a[i] > a[j]) dp[i] = max(dp[i], dp[j] + 1);
}
//因为最后一个dp不一定是答案, 所以要用一个变量记录一下
ans = max(dp[i], ans);
}
cout << ans << endl;

return 0;
}

js笔记01

发表于 2021-11-28

jQuery 语法

文档就绪事件

所有的实例中的所有 jQuery 函数位于一个 document ready 函数中:

1
2
3
4
5
$(document).ready(function(){

// 开始写 jQuery 代码...

});

简洁写法(与以上写法效果相同):

1
2
3
4
5
$(function(){

// 开始写 jQuery 代码...

});

JavaScript 入口函数:

1
2
3
window.onload = function () {
// 执行代码
}

jQuery 入口函数与 JavaScript 入口函数的区别:

  • jQuery 的入口函数是在 html 所有标签(DOM)都加载之后,就会去执行。
  • JavaScript 的 window.onload 事件是等到所有内容,包括外部图片之类的文件加载完后,才会执行。

jQuery 选择器

jQuery 选择器

jQuery 选择器允许您对 HTML 元素组或单个元素进行操作。

jQuery 选择器基于元素的 id、类、类型、属性、属性值等”查找”(或选择)HTML 元素。 它基于已经存在的 CSS 选择器,除此之外,它还有一些自定义的选择器。

jQuery 中所有选择器都以美元符号开头:$()。

元素选择器

jQuery 元素选择器基于元素名选取元素。

在页面中选取所有

元素:

1
$("p")
<i class="fa fa-angle-left"></i>1…345…7<i class="fa fa-angle-right"></i>

63 日志
1 分类
14 标签
© 2022 hydra
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.4