제출 #1327593

#제출 시각아이디문제언어결과실행 시간메모리
1327593sh_qaxxorov_571정렬하기 (IOI15_sorting)C++20
74 / 100
1096 ms12928 KiB
#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>

using namespace std;

// Yardımcı fonksiyon: R raundda sıralanıp sıralanamayacağını kontrol eder
bool check(int R, int N, vector<int> S, int M, int X[], int Y[], int P[], int Q[], bool fill_ans) {
    vector<int> cur_S = S;
    // Ermek'in hamlelerinden sonra hangi pozisyonun nereye gideceğini takip et
    vector<int> pos(N);
    iota(pos.begin(), pos.end(), 0);
    for (int i = 0; i < R; i++) {
        swap(pos[X[i]], pos[Y[i]]);
    }

    // Hedef: R hamle sonunda S[i] = i olmalı. 
    // Bunun için rüzgarın (Ermek) etkisini geri alarak başlangıçtaki 'ideal' hedefi bulalım.
    vector<int> target_val(N);
    for (int i = 0; i < N; i++) {
        target_val[pos[i]] = i;
    }

    // Şu anki S dizisindeki değerlerin yerini tutan bir yardımcı dizi
    vector<int> val_to_pos(N);
    for (int i = 0; i < N; i++) {
        val_to_pos[cur_S[i]] = i;
    }

    int swaps_needed = 0;
    vector<pair<int, int>> aizhan_swaps;

    for (int i = 0; i < N; i++) {
        // Eğer i. pozisyonda olması gereken hedef değer orada değilse swap yap
        if (cur_S[i] != target_val[i]) {
            int v1 = cur_S[i];
            int v2 = target_val[i];
            int p1 = i;
            int p2 = val_to_pos[v2];

            aizhan_swaps.push_back({p1, p2});
            
            swap(cur_S[p1], cur_S[p2]);
            val_to_pos[v1] = p2;
            val_to_pos[v2] = p1;
            swaps_needed++;
        }
    }

    if (swaps_needed > R) return false;

    // Eğer kontrol fonksiyonu 'true' ise ve cevap isteniyorsa P ve Q dizilerini doldur
    if (fill_ans) {
        cur_S = S;
        for (int i = 0; i < R; i++) {
            // 1. Ermek swap yapar
            swap(cur_S[X[i]], cur_S[Y[i]]);
            
            // Aizhan'ın yapacağı swapları gerçek zamanlı takip etmeliyiz
            // Çünkü Ermek her turda sayıların yerini değiştiriyor.
            if (i < (int)aizhan_swaps.size()) {
                // Aizhan'ın hedeflediği değerlerin o anki konumlarını bul
                int val1 = S[aizhan_swaps[i].first];
                int val2 = S[aizhan_swaps[i].second];
                
                // Başlangıçtaki S üzerinde de takip yapmalıyız ki 
                // Aizhan'ın hangi değerleri seçtiğini bilelim
                swap(S[aizhan_swaps[i].first], S[aizhan_swaps[i].second]);

                // Güncel dizide bu değerlerin nerede olduğunu bul
                int cur_p1 = -1, cur_p2 = -1;
                for(int j=0; j<N; j++) {
                    if(cur_S[j] == val1) cur_p1 = j;
                    if(cur_S[j] == val2) cur_p2 = j;
                }
                P[i] = cur_p1;
                Q[i] = cur_p2;
                swap(cur_S[P[i]], cur_S[Q[i]]);
            } else {
                // İhtiyaç yoksa etkisiz swap
                P[i] = 0;
                Q[i] = 0;
            }
        }
    }

    return true;
}

int findSwapPairs(int N, int S[], int M, int X[], int Y[], int P[], int Q[]) {
    vector<int> initial_S(N);
    for (int i = 0; i < N; i++) initial_S[i] = S[i];

    int low = 0, high = M, ans = M;
    
    // Minimum raundu bulmak için ikili arama
    while (low <= high) {
        int mid = (low + high) / 2;
        if (check(mid, N, initial_S, M, X, Y, P, Q, false)) {
            ans = mid;
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }

    // Bulunan minimum raund için gerçek swap listesini oluştur
    check(ans, N, initial_S, M, X, Y, P, Q, true);
    return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...