[programmers]2021 KAKAO BLIND RECRUITMENT-タクシー運賃
2021 KAO BLIND RECRUITMENT-乗り合わせタクシー料金
using Java 11
「タクシー料金の精算」の確認 import java.io.*;
import java.util.*;
public class Solution {
public static ArrayList<ArrayList<Node>> map = new ArrayList<>();
public static boolean[] visited;
public static int[] fare;
public static class Node implements Comparable<Node>{
int to;
int fare;
public Node(int to, int fare) {
this.to = to;
this.fare = fare;
}
@Override
public int compareTo(Node o) {
return this.fare- o.fare;
}
}
public static int getFare(int start, int s, int a, int b) {
PriorityQueue<Node> pq = new PriorityQueue<>();
pq.add(new Node(start, 0));
fare[start] = 0;
while(!pq.isEmpty()) {
Node curNode = pq.poll();
int next = curNode.to;
if(!visited[next]) {
visited[next] = true;
ArrayList<Node> arr = map.get(next);
for(int i = 0; i < arr.size(); i++) {
Node tmp = arr.get(i);
if(fare[tmp.to] > tmp.fare + fare[next]) {
fare[tmp.to] = tmp.fare + fare[next];
pq.add(new Node(tmp.to, fare[tmp.to]));
}
}
}
}
return fare[s] + fare[a] + fare[b];
}
public static int solution(int n, int s, int a, int b, int[][] fares) {
for(int i = 0; i <= n; i++) {
map.add(new ArrayList<>());
}
for(int i = 0; i < fares.length; i++) {
map.get(fares[i][0]).add(new Node(fares[i][1], fares[i][2]));
map.get(fares[i][1]).add(new Node(fares[i][0], fares[i][2]));
}
int min = Integer.MAX_VALUE;
for(int i = 1; i <= n; i++) {
visited = new boolean[n+1];
Arrays.fill(visited, false);
fare = new int[n+1];
Arrays.fill(fare, 1000001);
int result = getFare(i, s, a, b);
if(result < min) min = result;
}
return min;
}
}
📍 複数使用
まずアイデアを出すのはちょっと難しいです.
中間点を通過する最短経路問題は一般に2回のExpostで解決されるため,同様の方法で解決しようとするが,事実はそうではない.(似てるけど)
初めて思いついた方法
中間点(合乗セグメント)をノードmと呼ぶ
s->m,m->a,m->bの最短パスを見つけます.
mの範囲は1<=m<=nであるため、3*n回のマルチタスクを実行しなければならない.
見るからに効率テストは通らないと思います.また,効率的なタイムアウト現象も相次いでいる.ほほほ、だから私はいくつかのグーグルゲームをしました.
ダエストラで計算するとタイムアウトになるのでフロイド外シャーロット主義で解決・・・うん、でも変な頑固さなのか分からないし、Extraで解決したい.だから長い間考えていたアイデア
††逆に考えましょう
問題を見直したところ、与えられた地図は無方向図なので、料金は双方向です.ここには意図があるかもしれないと思うので、逆探索の方法を考えました.
出発地を中間点mとし,最短経路を求め,m->s,m->a,m->b最短経路を一度に求める.
この3つを合わせるといいです(料金はs->mと同じですから!)
共乗しない場合はm=sで解くので,すべての条件を調べることができる.
すなわち、始点1からnまで、n回の最短経路を求める場合は、dist[s]+dist[a]+dist[b]の値を返し、最小値を求めればよい.コードでは、チケットの手配はdistの手配に相当します.int min = Integer.MAX_VALUE;
for(int i = 1; i <= n; i++) {
visited = new boolean[n+1];
Arrays.fill(visited, false);
fare = new int[n+1];
Arrays.fill(fare, 1000001);
int result = getFare(i, s, a, b);
if(result < min) min = result;
}
📍 ディスクアレイの初期化
そう思ってやっと解けたのに、タイムアウト!(怒っています.)効率テスト用例7は1つ、、、、原因が分からないので、撮って修正して回って、正解だと言いました.😱 🥶 驚きと恐怖の瞬間だった.
他の質問に答えるときは、初めてInteger MAXVALUEで中間点のあるマルチアウトレットdist配列を埋めたときにオーバーフローが発生したことを覚えておいてください.(複数の結果が追加された場合)
そのため、最初は適当な数の「10000001」に設定します.結果効率は7回を超えた.普通に溢れたらタイムアウトじゃなくて失敗
数字が大きすぎて演算速度に影響するとは思わなかったが、そのまま撮るわけにはいかず、初値を「1000001」に変更して通過した.⁉️
それでたくさんの値段が変わりました
100,001 ❌
1,000,001 ⭕️
10000001❌(7回の効率テストに失敗)
10000001❌(効率テスト7回のみ失敗)
Integer.MAX_VALUE/3 - 1 ⭕️
:715827881ぐらいですが、fare[s]+fare[a]+fare[b]の計算値をオーバーフローさせたくなければ、この値でいいです.
一定値以上でタイムアウトが続くと理解しますが、うーん...
グーグルゲームをやってみても、説明する人はいません.(知っている方はコメントをお願いします)初期値を設定すると効率テストに影響しますが、一定の範囲内ではできないので、アルゴリズムを間違えるかもしれません.
Reference
この問題について([programmers]2021 KAKAO BLIND RECRUITMENT-タクシー運賃), 我々は、より多くの情報をここで見つけました
https://velog.io/@since1909/Programmers-합승택시요금
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import java.io.*;
import java.util.*;
public class Solution {
public static ArrayList<ArrayList<Node>> map = new ArrayList<>();
public static boolean[] visited;
public static int[] fare;
public static class Node implements Comparable<Node>{
int to;
int fare;
public Node(int to, int fare) {
this.to = to;
this.fare = fare;
}
@Override
public int compareTo(Node o) {
return this.fare- o.fare;
}
}
public static int getFare(int start, int s, int a, int b) {
PriorityQueue<Node> pq = new PriorityQueue<>();
pq.add(new Node(start, 0));
fare[start] = 0;
while(!pq.isEmpty()) {
Node curNode = pq.poll();
int next = curNode.to;
if(!visited[next]) {
visited[next] = true;
ArrayList<Node> arr = map.get(next);
for(int i = 0; i < arr.size(); i++) {
Node tmp = arr.get(i);
if(fare[tmp.to] > tmp.fare + fare[next]) {
fare[tmp.to] = tmp.fare + fare[next];
pq.add(new Node(tmp.to, fare[tmp.to]));
}
}
}
}
return fare[s] + fare[a] + fare[b];
}
public static int solution(int n, int s, int a, int b, int[][] fares) {
for(int i = 0; i <= n; i++) {
map.add(new ArrayList<>());
}
for(int i = 0; i < fares.length; i++) {
map.get(fares[i][0]).add(new Node(fares[i][1], fares[i][2]));
map.get(fares[i][1]).add(new Node(fares[i][0], fares[i][2]));
}
int min = Integer.MAX_VALUE;
for(int i = 1; i <= n; i++) {
visited = new boolean[n+1];
Arrays.fill(visited, false);
fare = new int[n+1];
Arrays.fill(fare, 1000001);
int result = getFare(i, s, a, b);
if(result < min) min = result;
}
return min;
}
}
int min = Integer.MAX_VALUE;
for(int i = 1; i <= n; i++) {
visited = new boolean[n+1];
Arrays.fill(visited, false);
fare = new int[n+1];
Arrays.fill(fare, 1000001);
int result = getFare(i, s, a, b);
if(result < min) min = result;
}
Reference
この問題について([programmers]2021 KAKAO BLIND RECRUITMENT-タクシー運賃), 我々は、より多くの情報をここで見つけました https://velog.io/@since1909/Programmers-합승택시요금テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol