5460. 好数对的数目
思路:直接按照题目要求找就可以啦
class Solution {
public int numIdenticalPairs(int[] nums) {
int ans=0;
for(int i=0;i
5461. 仅含 1 的子串数
思路:每次遇到‘1’时,计算下以这个点结尾能组成的连续1串的数量即可。
class Solution {
public int numSub(String s) {
long ans = 0;
int mod = 1000000007;
int last = -1;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '1') {
if (last == -1) last = i;
ans = (ans + i - last + 1) % mod;
} else
last = -1;
}
return (int)ans;
}
}
5211. 概率最大的路径
思路:最短路变形,没什么好说的,因为n很大,我这里采用SPFA算法。
class Solution {
class node{
int v;
double p;
public node(int v,double p){
this.v=v;
this.p=p;
}
}
double[] dp;
List> list;
public double maxProbability(int n, int[][] edges, double[] succProb, int start, int end) {
dp = new double[n];
list = new ArrayList<>();
boolean[] used = new boolean[n];
for (int i = 0; i < n; i++)
list.add(new ArrayList<>());
for (int i = 0; i < edges.length; i++) {
list.get(edges[i][0]).add(new node(edges[i][1], succProb[i]));
list.get(edges[i][1]).add(new node(edges[i][0], succProb[i]));
}
dp[start] = 1.0;
Queue q = new LinkedList<>();
q.add(start);
used[start] = true;
while (!q.isEmpty()) {
int now = q.poll();
used[now] = false;
for (int i = 0; i < list.get(now).size(); i++) {
node next = list.get(now).get(i);
if (dp[now] * next.p > dp[next.v]) {
dp[next.v] = dp[now] * next.p;
if (!used[next.v]) {
q.add(next.v);
used[next.v] = true;
}
}
}
}
return dp[end];
}
}
5463. 服务中心的最佳位置
思路:这个题的类似题很早就见过了,比如说我之前写的这道题:吊打XXX。于是我上去直接蟒了模拟退火,但是因为精度问题一直wrong,这里我先贴出我精度不符合要求的版本。再放篇参考题解的代码。
class Solution {
class node {
double x, y;
public node(double x, double y) {
this.x = x;
this.y = y;
}
}
node now, ans, A;
int[][] pos;
double min_dis = Double.MAX_VALUE;
public double getMinDistSum(int[][] positions) {
this.pos = positions;
ans = new node(0, 0);
for (int i = 0; i < pos.length; i++) {
ans.x += pos[i][0];
ans.y += pos[i][1];
}
ans.x /= pos.length;
ans.y /= pos.length;
work(1000001);
return min_dis;
}
private double find_dis(node a) {
double res = 0;
for (int i = 0; i < pos.length; i++)
res += dis(a, new node(pos[i][0], pos[i][1]));
return res;
}
private void work(double T) {
now = new node(ans.x, ans.y);
while (T > 0.01) {
A = new node(now.x + T * (Math.random() * 2 - 1), now.y + T * (Math.random() * 2 - 1));
double dE = jud(now) - jud(A);
if (dE > 0 || Math.random() <= Math.exp(dE / T))
now = new node(A.x, A.y);
T *= 0.99;
}
for (int i = 0; i <= 2000; i++) {
A.x = ans.x + T * (Math.random() * 2 - 1);
A.y = ans.y + T * (Math.random() * 2 - 1);
jud(A);
}
}
private double jud(node now) {
double res = 0;
for (int i = 0; i < pos.length; i++)
res += dis(now, new node(pos[i][0], pos[i][1]));
if (res < min_dis) {
min_dis = res;
ans = new node(now.x, now.y);
}
return res;
}
private double dis(node a, node b) {
return Math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
}
参考题解一(模拟退火,其实已经退化到梯度下降了):
class Solution {
class node {
double x, y;
public node(double x, double y) {
this.x = x;
this.y = y;
}
}
private static final double t = 0.98;
private static final double eps = 1e-8;
private int[] dx = new int[]{-1, 1, 0, 0};
private int[] dy = new int[]{0, 0, 1, -1};
public double getMinDistSum(int[][] positions) {
double x = 0, y = 0;
double ret = 1e18;
double step = 100;
while (step > eps) {
boolean flag = true;
while (flag) {
flag = false;
for (int i = 0; i < 4; i++) {
double nx = x + dx[i] * step;
double ny = y + dy[i] * step;
double tmp = 0;
for (int j = 0; j < positions.length; j++)
tmp += dis(new node(positions[j][0], positions[j][1]), new node(nx, ny));
if (tmp < ret) {
ret = tmp;
x = nx;
y = ny;
flag = true;
}
}
}
step *= t;
}
return ret;
}
private double dis(node a, node b) {
return Math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
}