提交 029f5834 编写于 作者: qq_36480062's avatar qq_36480062

c

上级 f1196168
......@@ -43,4 +43,4 @@ public class 树的重心 {
ne[cnt] = he[a];
he[a] = cnt++;
}
}
}
\ No newline at end of file
package DFS;
public class 重复性剪枝 {
public static void main(String[] args) {
for (int i = 0; i < 30; i++) {
a[i] = i + 1;
}
long s = System.nanoTime();
dfs(0, 0, 0);
System.out.println(ans);
long t = System.nanoTime();
System.out.println((t - s) / 1e9);
s = System.nanoTime();
ddf(0, 0, 0);
t = System.nanoTime();
System.out.println((t - s) / 1e9);
System.out.println(te);
}
static int n = 30, k = 11, ans, te, sum = 200;
static int[] a = new int[30];
static boolean[] vis = new boolean[30];
//当前位置,当前和 w选了多少个
static void dfs(int cnt, int s, int w) {
// if (k - w > n - cnt + 1) return;
if (s > sum || w > k) return;
if (cnt == n) {
if (s == sum && w == k) {
ans++;
}
return;
}
dfs(cnt + 1, s + a[cnt], w + 1);
dfs(cnt + 1, s, w);
}
static void ddf(int s, int cnt, int pos) {
if (s > sum || cnt > k) return;
if (s == sum && cnt == k) {
te++;
return;
}
//pos位置
for (int i = pos; i < n; i++) {
if (!vis[i]) {
vis[i] = true;
ddf(s + a[i], cnt + 1, i + 1);
vis[i] = false;
}
}
}
}
package String;
/**
*
*/
public class 前缀统计 {
public static void main(String[] args) {
}
}
package basic.queue;
import java.io.*;
import java.util.LinkedList;
import java.util.ArrayDeque;
import java.util.StringTokenizer;
import static java.lang.System.in;
......@@ -95,7 +95,7 @@ public class 单调队列 {
static int[] q = new int[(int) (1e6 + 10)];
static int n, k;
static LinkedList<Integer> queue = new LinkedList<Integer>();
static ArrayDeque<Integer> queue = new ArrayDeque<Integer>();
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static BufferedReader reader = new BufferedReader(new InputStreamReader(in));
static StringTokenizer tokenizer = new StringTokenizer("");
......
package basic.sort;
import java.util.Scanner;
/**
* 给定一个长度为n的整数数列,请你计算数列中的逆序对的数量。
* 逆序对的定义如下:对于数列的第 i 个和第 j 个元素,如果满足 i < j 且 a[i] > a[j],则其为一个逆序对;否则不是。
......@@ -18,8 +20,34 @@ package basic.sort;
*/
public class 逆序对 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
System.out.println(merge(0, n - 1));
}
private static long merge(int l, int r) {
if (l >= r) return 0;
int mid = l + r >> 1;
long res = merge(l, mid) + merge(mid + 1, r);
int k = 0, i = l, j = mid + 1;
while (i <= mid && j <= r) {
if (a[i] <= a[j]) temp[k++] = a[i++];
else {
temp[k++] = a[j++];
res += mid - i + 1;
}
}
while (i <= mid) temp[k++] = a[i++];
while (j <= r) temp[k++] = a[j++];
for (i = l, j = 0; i <= r; i++, j++) a[i] = temp[j];
return res;
}
static int[] a = new int[100010];
static int[] temp = new int[100010];
static int n;
}
package doublePointer;
import java.util.Scanner;
/**
* 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
* 假设字符串中只包含从’a’到’z’的字符。
* 样例
* 输入:"abcabc"
* 输出:3
* 分析:
* 双指针法,第一个指针i从头开始遍历,同时将哈希表的值++,
* 一旦遇见重复的,则从j开始遍历,同时哈希表值--,
* 直到遍历到重复的那个值位置,j为该位置++,重复上述过程。
* 这一方法与数组连续子序列最大和有点像,不过那个是遇见累加和为负数就重新规划起点,
* 本题是遇见重复的就重新规划起点。
*/
public class 最长不含重复字符的子字符串 {
static int[] a = new int[100100];
static int[] ha = new int[26];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.next();
int sl = s.length();
int ans = 0;
for (int i = 0, j = 0; i < sl; i++) {
ha[s.charAt(i) - 'a']++;
while (ha[s.charAt(i) - 'a'] > 1) {
ha[s.charAt(j) - 'a']--;
j++;
}
ans = Math.max(ans, i - j + 1);
}
System.out.println(ans);
}
}
package doublePointer;
import java.util.HashMap;
import java.util.Scanner;
/**
......@@ -44,6 +45,28 @@ public class 最长连续不重复子序列 {
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
f();
}
static HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
static void f() {
int ans = 0;
for (int i = 0, j = 0; i < n; i++) {
if (!map.containsKey(a[i])) {
map.put(a[i], 1);
} else map.put(a[i], map.get(a[i]) + 1);
while (map.get(a[i]).compareTo(1) > 0) {
map.put(a[j], map.get(a[j]) - 1);
j++;
}
ans = Math.max(ans, i - j + 1);
}
System.out.println(ans);
}
static void hash() {
int ans = 0;
for (int i = 0, j = 0; i < n; i++) {
//i往前走
......
package graph;
import java.util.Scanner;
/**
* 给定一个n个点m条边的有向图,图中可能存在重边和自环,边权可能为负数。
* 再给定k个询问,每个询问包含两个整数x和y,表示查询从点x到点y的最短距离,如果路径不存在,则输出“impossible”。
* 数据保证图中不存在负权回路。
* 输入格式
* 第一行包含三个整数n,m,k
* 接下来m行,每行包含三个整数x,y,z,表示点x和点y之间存在一条有向边,边长为z。
* 接下来k行,每行包含两个整数x,y,表示询问点x到点y的最短距离。
* 输出格式
* 共k行,每行输出一个整数,表示询问的结果,若询问两点间不存在路径,则输出“impossible”。
* 数据范围
* 1≤n≤200,
* 1≤k≤n^2
* 1≤m≤20000,
* 图中涉及边长绝对值均不超过10000。
* 输入样例:
* 3 3 2
* 1 2 1
* 2 3 2
* 1 3 1
* 2 1
* 1 3
* 输出样例:
* impossible
* 1
* 多源最短路问题,采用Floyd算法,时间复杂度为O(n^3)。
* Floyd算法的思想是动态规划。设d[i][j]表示i点到j点的最短距离,
* i点到j点中间经过某点k,则状态转移方程为d[i][j] = min(d[i][k] + d[k][j],d[i][j])(1<=k<=n);
* 然后用三重循环实现该状态扩散的过程即可。注意对中间节点k的枚举需要放在循环的最外层,否则会出错。
* 使用邻接矩阵存图
* 边长最多10000最多20000边,则最长路径就是2*10^8
* 初始化为int/2即可
* 即使全是负权边,int/2-2*10^8,无穷-常数还是无穷
* 如何判别无穷呢,显然 int/4>2*10^8
*/
public class floyd {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
k = sc.nextInt();
int x, y, z, t = Integer.MAX_VALUE / 2;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i == j) g[i][j] = 0;
else g[i][j] = t;
}
}
for (int i = 0; i < m; i++) {
x = sc.nextInt();
y = sc.nextInt();
z = sc.nextInt();
g[x][y] = Math.min(g[x][y], z);
}
floyd();
while (k-- != 0) {
x = sc.nextInt();
y = sc.nextInt();
if (g[x][y] > t / 2) System.out.println("Imposs");
else System.out.println(g[x][y]);
}
}
static void floyd() {
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
g[i][j] = Math.min(g[i][k] + g[k][j], g[i][j]);
}
}
}
}
static int n, m, k;
static int[][] g = new int[210][210];
}
package graph;
import java.util.Arrays;
import java.util.Scanner;
/**
* 给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数。
* 请你求出从1号点到n号点的最多经过k条边的最短距离,如果无法从1号点走到n号点,输出impossible。
* 注意:图中可能 存在负权回路 。
* 输入格式
* 第一行包含三个整数n,m,k。
* 接下来m行,每行包含三个整数x,y,z,表示点x和点y之间存在一条有向边,边长为z。
* 输出格式
* 输出一个整数,表示从1号点到n号点的最多经过k条边的最短距离。
* 如果不存在满足条件的路径,则输出“impossible”。
* 数据范围
* 1≤n,k≤500,
* 1≤m≤10000,
* 任意边长的绝对值不超过10000。
* 输入样例:
* 3 3 1
* 1 2 1
* 2 3 1
* 1 3 3
* 输出样例:
* 3
*/
public class 边权限制最短路 {
static class node {
int x, y, z;
public node(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
}
static node[] node = new node[10005];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
k = sc.nextInt();
for (int i = 0; i < m; i++) {
node[i] = new node(sc.nextInt(), sc.nextInt(), sc.nextInt());
}
if (blm() == -1) System.out.println("Imposttb");
else System.out.println(dis[n]);
}
private static int blm() {
Arrays.fill(dis, Integer.MAX_VALUE / 2);
dis[1] = 0;
for (int i = 0; i < k; i++) {
tem = Arrays.copyOf(dis, dis.length);
for (int j = 0; j < m; j++) {
dis[node[j].y] = Math.min(dis[node[j].y], tem[node[j].x] + node[j].z);
}
}
if (dis[n] > Integer.MAX_VALUE / 4) return -1;
return dis[n];
}
static int[] dis = new int[502];
static int[] tem;
static int n, m, k;
}
package greedy;
/**
* 给定N个闭区间[ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。
* 输出选择的点的最小数量。位于区间端点上的点也算作区间内。
* 输入格式
* 第一行包含整数N,表示区间数。
* 接下来N行,每行包含两个整数ai,bi,表示一个区间的两个端点。
* 输出格式
* 输出一个整数,表示所需的点的最小数量。
* 数据范围
* 1≤N≤10^5,
* −10^9≤ai≤bi≤10^9
* 输入样例:
* 3
* -1 1
* 2 4
* 3 5
* 输出样例:
* 2
*
* 本题是区间贪心的经典题,要求选出尽可能少的点,使得所有区间都有包含的点。
* 相当于给学生发书,每个人有空的时间是一段区间,要求尽可能少的选择若干个时间点,
* 将书发放给所有的学生。这类贪心问题一般按照所有区间的右端点从小到大排序,
* 然后选择按照右端点自小到大的遍历区间,如果某个区间内没有选择点,则选择区间的右端点。
* 比如按照区间右端点排序得到[1,3],[2,5],[4,6],第一个点选择3,
* 然后判断下第二个区间是否包含3,由于第二个区间右端点是大于3的,
* 只需要左端点小于3便与第一个区间有了交集,即[l1,r1],[l2,r2],有r1 < r2;
* 当l2 < r1时两个区间有交集,且第一个区间右端点r1必然在两个区间交集内。2 < 3,
* 所以第二个区间包含3,故遍历到下一个区间[4,6],4 > 3,所以不包含3,选择第二个点6。
*
* 至于为什么对右端点自小到大排序后每次要选择右端点,
* 因为如果两个区间有交集,右端点较小的那个区间的右端点必然处于两个区间的交集内。
* 下面证明这样选择的点是最少的。我们知道,每次需要选择一个新的点的时候都有当前遍历到区间的左端点大于上一个被选择区间的右端点,即有多少个点被选择,原来的区间集合就存在多少个互不相交的区间,因此,这样选择的点数是最少的。
*/
public class 区间选点 {
public static void main(String[] args) {
}
}
......@@ -3,7 +3,11 @@ package 数学;
//线性筛质数
public class 线性筛 {
public static void main(String[] args) {
oldN(1234567);
long s = System.nanoTime();
oldN(4234567);
long t = System.nanoTime();
System.out.println((t - s) / 1e9);
}
static int cnt = 0;
......@@ -23,11 +27,11 @@ public class 线性筛 {
}
static void oldN(int N) {
int n = 3000000;
int n = 6000000;
int r = 0;
while ((n / Math.log(n)) < N) {
r++;
n += 3000;
n += 5000;
}
System.out.println(r);
int cnt = 0;
......
package 树形dp;
import java.util.Arrays;
import java.util.Scanner;
/**
* 鲍勃喜欢玩电脑游戏,特别是战略游戏,但有时他找不到解决问题的方法,这让他很伤心。
* 现在他有以下问题。
* 他必须保护一座中世纪城市,这条城市的道路构成了一棵树。
* 每个节点上的士兵可以观察到所有和这个点相连的边。
* 他必须在节点上放置最少数量的士兵,以便他们可以观察到所有的边。
* 你能帮助他吗?
* 例如,下面的树:
* 只需要放置1名士兵(在节点1处),就可观察到所有的边。
* 输入格式
* 输入包含多组测试数据,每组测试数据用以描述一棵树。
* 对于每组测试数据,第一行包含整数N,表示树的节点数目。
* 接下来N行,每行按如下方法描述一个节点。
* 节点编号:(子节点数目) 子节点 子节点 …
* 节点编号从0到N-1,每个节点的子节点数量均不超过10,每个边在输入数据中只出现一次。
* 输出格式
* 对于每组测试数据,输出一个占据一行的结果,表示最少需要的士兵数。
* 数据范围
* 0<N≤1500
* 输入样例:
* 4
* 0:(1) 1
* 1:(2) 2 3
* 2:(0)
* 3:(0)
* 5
* 3:(3) 1 4 2
* 1:(1) 0
* 2:(0)
* 0:(0)
* 4:(0)
* 输出样例:
* 1
* 2
*/
public class 战略游戏 {
public static void main(String[] args) {
System.out.println();
Scanner sc = new Scanner(System.in);
int t, w;
while (sc.hasNext()) {
n = sc.nextInt();
Arrays.fill(vis, false);
cnt = 1;
for (int i = 0; i < n; i++) {
t = sc.nextInt();
}
}
}
static boolean[] vis = new boolean[1502];
static int n, cnt = 1;
static int[] he = new int[1502];
static int[] ne = new int[1502];
static int[] e = new int[1502];
static int[][] f = new int[1502][2];
static void add(int a, int b) {
e[cnt] = b;
ne[cnt] = he[a];
he[a] = cnt++;
}
static void dfs(int u) {
f[u][0] = 0;
f[u][1] = 1;
for (int i = he[u]; i != 0; i = ne[i]) {
int j = e[i];
dfs(j);
f[u][0] += f[j][1];
f[u][1] += Math.min(f[j][1], f[j][0]);
}
}
}
package 树形dp;
public class 树的中心 {
public static void main(String[] args) {
}
}
......@@ -40,7 +40,7 @@ public class 树重心找节点 {
}
maxpart[u] = Math.max(maxpart[u], n - size[u]);
//算出以u为根,u的父节点所在联通分量的节点数目
//算出以u为根的子树,u的父节点所在联通分量的节点数目
ans = Math.min(ans, maxpart[u]);
}
//4, 5, 8, 7, 8, 5, 6, 8, 8,
......
......@@ -27,7 +27,7 @@ import java.util.Scanner;
*/
public class LIS {
public static void main(String[] args) {
int[] arr = {2, 4, 2, 2, 4};
int[] arr = {2, 4, 2, 3, 4};
System.out.println(LIS(arr));
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
......
package 线性dp.数字三角形模型;
import java.util.Scanner;
/**
* http://acm.hdu.edu.cn/showproblem.php?pid=1978
* 求方案数量
* 有限制的方案数量
*/
public class HDoj1978多少条路 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
t = sc.nextInt();
while (t-- != 0) {
n = sc.nextInt();
m = sc.nextInt();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
a[i][j] = sc.nextInt();
dp[i][j] = -1;
}
}
System.out.println(dfs(1, 1));
}
}
static int dfs(int x, int y) {
int t = 0;
if (dp[x][y] >= 0) return dp[x][y];
if (x == n && y == m) return 1;
for (int i = 0; i <= a[x][y]; i++) {
for (int j = 0; j <= a[x][y] - i; j++) {
if (inarea(x + i, y + j) && i + j != 0) {
t += dfs(x + i, y + j);
t %= mod;
}
}
}
return dp[x][y] = t;
}
private static boolean inarea(int x, int y) {
return x >= 1 && x <= n && y >= 1 && y <= m;
}
static int[][] dp = new int[110][110];
static int[][] a = new int[110][110];
static int t, n, m, mod = 10000;
}
package 线性dp.数字三角形模型;
/**
* X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。
*   地宫的入口在左上角,出口在右下角。
*   小明被带到地宫的入口,国王要求他只能向右或向下行走。
*   走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。
*   当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。
*   请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。
* 输入格式
*   输入一行3个整数,用空格分开:n m k (1<=n,m<=50, 1<=k<=12)
*   接下来有 n 行数据,每行有 m 个整数 Ci (0<=Ci<=12)代表这个格子上的宝物的价值
* 输出格式
*   要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。
* 样例输入
* 2 2 2
* 1 2
* 2 1
* 样例输出
* 2
* 样例输入
* 2 3 2
* 1 2 3
* 2 1 5
* 样例输出
* 14
*/
public class 地宫取宝 {
public static void main(String[] args) {
}
static int dfs(int x, int y, int num, int max) {
if (f[x][y][num][max + 1] != -1) {
return f[x][y][num][max + 1];
}
if (x > n || y > m || num > k) return 0;
if (x == n && y == m) {
if (num == k || (num == k - 1 && max < g[x][y]))
return f[x][y][num][max + 1] = 1;
else return f[x][y][num][max + 1] = 0;
}
long s = 0;
if (x + 1 <= n) {//判断合法性
if (max < g[x][y]) {
}
}
return f[x][y][num][max + 1];
}
static int n, m, k;
static int[][] g = new int[51][51];
static int[][][][] f = new int[51][51][14][14];
}
package 线性dp.背包模型;
import java.util.Scanner;
/**
* 一个正整数n可以表示成若干个正整数之和,形如:n=n1+n2+…+nk,其中n1≥n2≥…≥nk,k≥1。
* 我们将这样的一种表示称为正整数n的一种划分。
* 现在给定一个正整数n,请你求出n共有多少种不同的划分方法。
* 输入格式
* 共一行,包含一个整数n。
* 输出格式
* 共一行,包含一个整数,表示总划分数量。
* 由于答案可能很大,输出结果请对10^9+7
* 取模。
* 数据范围
* 1≤n≤1000
* 输入样例:
* 5
* 输出样例:
* 7
* 可以看成完全背包问题求方案数
* 定义状态为:f[i,j]为前i个物品可选(1-i)总和为j的方案数
* 状态划分,考虑last
* 划分成两个部分:
* 不选第i个物品:f[i-1,j]
* 选上第i个物品k个:f[i-1,j]+f[i-1,j-i]+f[i-1,j-2i]+...f[i-1,j-ki] (j>=ki)
* f[i-1,j-i]= f[i-1,j-2i]+...f[i-1,j-ki]
* 则f[i,j]=f[i-1,j]+f[i-1,j-i]
*/
public class 整数划分 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
dp[0]=1;
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j++) {
dp[j] = (dp[j]+dp[j - i])%mod;
}
}
System.out.println(dp[n]);
}
static int[] dp = new int[1005];
static int n, mod = (int) (1e9 + 7);
}
......@@ -58,8 +58,8 @@ public class 树状数组区间修改 {
}
static int maxn = 500001, n, m;
static long tree[] = new long[maxn];
static long cha[] = new long[maxn];
static long[] tree = new long[maxn];
static long[] cha = new long[maxn];
//差分数组
static void add(int s, int value) {
......
package 组合dp;
import java.util.Scanner;
/**
* 给定n组询问,每组询问给定两个整数a,b,请你输出C(a,b) mod (10^9+7)的值。
* 输入格式
* 第一行包含整数n。接下来n行,每行包含一组a和b。
* 输出格式
* 共n行,每行输出一个询问的解。
* 数据范围
* 1≤n≤10000,1≤b≤a≤2000
* 输入样例:
* 3
* 3 1
* 5 3
* 2 2
* 输出样例:
* 3
* 10
* 1
* 求组合数,预处理!!!
* 本题b和a的范围均不超过2000,故我们可以预处理出所有组合数的值,
* 一个1 + 2 +...+2000 = 1000 * 2001约等于两百万,
* 故可以在一秒内计算完成。具体的求法利用了组合数的递推式C(n,m) = C(n - 1,m) + C(n - 1,m - 1)。
* 该递推式的推导使用的是类似于dp的思想,C(n,m)
* 表示在n个物品中选出m个物品的选法,可以划分为两种情况,
* 第一种情况是m个物品均来自前n-1个物品,一共C(n-1,m)中选法;
* 第二种情况是m - 1个物品来自前n - 1个物品,最后一个物品来自第n个物品,
* 一共C(n-1,m-1)种选法,故可以得到C(n,m) = C(n - 1,m) + C(n - 1,m - 1)。
* 边界情况为一个都不选的情况,方案数为1。
*/
public class 求组合数1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
int x, y;
for (int i = 0; i < 2000; i++) {
for (int j = 0; j <= i; j++) {
if (j == 0) f[i][j] = 1;
else f[i][j] = (f[i - 1][j] + f[i - 1][j - 1]) % mod;
}
}
while (n-- != 0) {
x = sc.nextInt();
y = sc.nextInt();
System.out.println(f[x][y]);
}
}
static int[][] f = new int[2005][2005];
static int n, mod = (int) (1e9 + 7);
}
package dp;
import java.util.Scanner;
/**
* http://acm.hdu.edu.cn/showproblem.php?pid=1978
*/
public class HDoj1978多少条路 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
t = sc.nextInt();
while (t-- != 0) {
n = sc.nextInt();
m = sc.nextInt();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
a[i][j] = sc.nextInt();
dp[i][j] = -1;
}
}
System.out.println(dfs(1, 1));
}
}
static int dfs(int x, int y) {
int t = 0;
if (dp[x][y] >= 0) return dp[x][y];
if (x == n && y == m) return 1;
for (int i = 0; i <= a[x][y]; i++) {
for (int j = 0; j <= a[x][y] - i; j++) {
if (inarea(x + i, y + j) && i + j != 0) {
t += dfs(x + i, y + j);
t %= mod;
}
}
}
return dp[x][y] = t;
}
private static boolean inarea(int x, int y) {
return x >= 1 && x <= n && y >= 1 && y <= m;
}
static int[][] dp = new int[110][110];
static int[][] a = new int[110][110];
static int t, n, m, mod = 10000;
}
......@@ -7,8 +7,6 @@ import java.util.Scanner;
import static java.lang.System.in;
/**
*
*
* 5 6
* 1 2 7 5
* 1 3 4 2
......@@ -17,7 +15,7 @@ import static java.lang.System.in;
* 3 4 10 1
* 4 5 8 5
* 1 5 10
*
* <p>
* 5 6
* 1 2 7 5
* 1 3 4 2
......@@ -26,12 +24,12 @@ import static java.lang.System.in;
* 3 4 10 1
* 4 5 8 5
* 1 5 4
*
* <p>
* Sample Output
* Case 1:
* maximum height = 7
* length of shortest route = 20
*
* <p>
* Case 2:
* maximum height = 4
* length of shortest route = 8
......
......@@ -35,9 +35,20 @@ public class HDoj1016素数环 {
static int[] circle;
static boolean[] vis;
/**
* 显然能被2的倍数整除,就一定能被2整除
* 就少枚举一半的约数
* 直接快一半!!!
*
* @param x
* @return
*/
static boolean isPrimer(int x) {
if (x < 2) return false;
if (x == 2) return true;
if ((x & 1) == 0) return false;
int t = (int) Math.sqrt(x);
for (int i = 2; i <= t; i++) {
for (int i = 3; i <= t; i += 2) {
if (x % i == 0) return false;
}
return true;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册