Skip to content

Commit 066163a

Browse files
committed
add acwing: basic-chapter1-802
1 parent d8ddb8a commit 066163a

File tree

2 files changed

+157
-1
lines changed

2 files changed

+157
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
package acwing.basic.chapter1;
2+
3+
import java.io.BufferedReader;
4+
import java.io.IOException;
5+
import java.io.InputStreamReader;
6+
import java.util.ArrayList;
7+
import java.util.Collections;
8+
import java.util.List;
9+
10+
/**
11+
* @author : CodeWater
12+
* @create :2022-07-06-18:49
13+
* @Function Description :802.区间和
14+
*/
15+
public class _802IntervalAns {
16+
/**
17+
* 数据范围比较小,可以选用前缀和。
18+
* 本题范围较大,考虑一下离散化,本题范围是(-10^9 , 10^9),但是最多用到30w(n+2m)个坐标。
19+
* 把用到的坐标排序映射到从0开始的
20+
* (当然也有其他的做法)
21+
*/
22+
23+
24+
public static int N = 300010;
25+
// a存储数的 s前缀和数组
26+
public static int[] a = new int[N];
27+
public static int[] s = new int[N];
28+
// alls存所有要离散化的值
29+
public static List<Integer> alls = new ArrayList<>();
30+
// 操作数组:add 添加一个数 query查询
31+
public static List<PII> add = new ArrayList<>();
32+
public static List<PII> query = new ArrayList<>();
33+
34+
public static void main(String[] args) throws IOException {
35+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
36+
String[] str = br.readLine().split(" ");
37+
int n = toInt(str[0]), m = toInt(str[1]);
38+
39+
for (int i = 0; i < n; i++) {
40+
str = br.readLine().split(" ");
41+
int x = toInt(str[0]), c = toInt(str[1]);
42+
// 在下标x的位置处加上c 存入add数组
43+
add.add(new PII(x, c));
44+
// 存入要离散化的下标
45+
alls.add(x);
46+
}
47+
48+
for (int i = 0; i < m; i++) {
49+
str = br.readLine().split(" ");
50+
int l = toInt(str[0]), r = toInt(str[1]);
51+
// 存入query数组,要查询的范围
52+
query.add(new PII(l, r));
53+
// 存入要离散化的查询下标
54+
alls.add(l);
55+
alls.add(r);
56+
}
57+
58+
// 去重:1.排序 2.去除重复元素
59+
Collections.sort(alls);
60+
int unique = unique(alls);
61+
alls = alls.subList(0, unique);
62+
63+
// 处理在离散化之后坐标上加上值
64+
for (PII item : add) {
65+
// 离散化之后的下标
66+
int x = find(item.first, alls);
67+
a[x] += item.second;
68+
}
69+
70+
// 预处理前缀和(这里映射到(1,size))
71+
for (int i = 1; i <= alls.size(); i++) s[i] = s[i - 1] + a[i];
72+
73+
// 处理m个询问
74+
for (PII item : query) {
75+
int l = find(item.first, alls), r = find(item.second, alls);
76+
System.out.println(s[r] - s[l - 1]);
77+
}
78+
}
79+
80+
// 找到离散化之后的x的下标
81+
public static int find(int x, List<Integer> alls) {
82+
int l = 0, r = alls.size() - 1;
83+
while (l < r) {
84+
int mid = l + r >> 1;
85+
if (alls.get(mid) >= x) r = mid;
86+
else l = mid + 1;
87+
}
88+
//映射到从1开始的自然数,因为这道题会用到前缀和,所用从1开始,减少一些边界情况
89+
return r + 1;
90+
}
91+
92+
// 双指针:去除重复元素,也就是返回一段不重复元素的下标
93+
public static int unique(List<Integer> list) {
94+
int j = 0;
95+
// i遍历所有的数 j保存的是当前存到了哪个数(j<= i)
96+
for (int i = 0; i < list.size(); i++) {
97+
// 满足:当前是第一个数 ;当前数和上一个数不等。 那就把当前位置的数换成不重复的j
98+
if (i == 0 || list.get(i) != list.get(i - 1)) {
99+
list.set(j++, list.get(i));
100+
}
101+
// 前后两个数相等,i指针往后走,j不动
102+
}
103+
// for结束之后从(0,j-1)就是所有不重复的元素了
104+
return j;
105+
}
106+
107+
public static int toInt(String str) {
108+
return Integer.parseInt(str);
109+
}
110+
111+
112+
}
113+
114+
// PII要操作的数据类型
115+
class PII implements Comparable<PII> {
116+
// 这里为了方便就不设置私有。(如果要求规范一点,还是写个方法他返回比较好)
117+
public int first, second;
118+
119+
// public int getFirst(){
120+
// return first;
121+
// }
122+
123+
// public int getSecond(){
124+
// return second;
125+
// }
126+
127+
public PII(int first, int second) {
128+
this.first = first;
129+
this.second = second;
130+
}
131+
132+
@Override
133+
public int compareTo(PII o) {
134+
return this.first - o.first;
135+
}
136+
}

Algorithm/src/offer/_13RangeOfMotionOfRobot.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
3030
*/
3131
public class _13RangeOfMotionOfRobot {
32-
32+
//==========================广搜============================
3333
public int movingCount(int m, int n, int k) {
3434
// k为0,机器人只能在当前这个格子
3535
if (k == 0) return 1;
@@ -70,4 +70,24 @@ public int get(int x) {
7070
}
7171

7272

73+
//==========================深搜============================
74+
class Solution {
75+
int m , n , k ;
76+
boolean[][] visited;
77+
public int movingCount(int m, int n, int k) {
78+
this.m = m ; this.n = n ; this.k = k ;
79+
this.visited = new boolean[m][n];
80+
return dfs( 0 , 0 , 0 , 0 );
81+
}
82+
83+
// si表示i行标的数位和,sj表示j列标的数位和
84+
public int dfs( int i , int j , int si , int sj ){
85+
// 1.不在合理范围内 2.k < si + sj 行列数位和超出k 3. 已经访问过该位置
86+
if( i >= m || j >= n || k < si + sj || visited[i][j] )return 0;
87+
visited[i][j] = true;
88+
return 1 + dfs( i + 1 , j , (i + 1) % 10 != 0 ? si + 1 : si - 8 , sj ) +
89+
dfs( i , j + 1 , si , (j + 1) % 10 != 0 ? sj + 1 : sj - 8 );
90+
}
91+
92+
}
7393
}

0 commit comments

Comments
 (0)