#45198: 大神救我


Xcode (Xcode)

School : 臺北市立建國高級中學
ID : 156489
IP address : [111.241.78.65]
Last Login :
2025-04-09 19:09:55
e790. a1.倉庫整理 (Warehouse) -- 2019年12月TOI練習賽 | From: [111.241.94.44] | Post Date : 2025-01-24 14:25

 這是我目前因為TLE修改的程式碼,但改了以後更後面的測資依然TLE:

#include <iostream>

 using namespace std;

 

 int count2 = 0;

 bool flag = false;

 void Towers(int n,char a,char b,char c, int i);

 

 

 

 int main() {

     int n, i;

     cin >> n >> i;

     Towers(n,'1','2','3', i);

     cout << "\n";

     return 0;

 }

 

 void Towers(int n,char a,char b,char c, int i){

     if(n==1){

         if (flag == true){

             return;

         }

         if (count2 == i-1){

             cout<<"move "<<n<<" from "<<a<<" to "<<c<<endl;

             flag = true;

         }

         count2++;

     }

     else{

         if (flag == true){

             return;

         }

         Towers(n-1,a,c,b, i);

         if (count2 == i-1){

             cout<<"move "<<n<<" from "<<a<<" to "<<c<<endl;

             flag = true;

         }

         count2++;

         Towers(n-1,b,a,c, i);

         

     }

 }

 

#12: 5% TLE (1s)

Killed
 
#45235: Re: 大神救我


leeguanhan0909@gmail.com (李冠翰)

School : 高雄市苓雅區復華高級中學國中部
ID : 276558
IP address : [36.238.153.220]
Last Login :
2025-04-05 17:05:47
e790. a1.倉庫整理 (Warehouse) -- 2019年12月TOI練習賽 | From: [218.166.7.65] | Post Date : 2025-01-31 17:28

 這是我目前因為TLE修改的程式碼,但改了以後更後面的測資依然TLE:

#include

 using namespace std;

 

 int count2 = 0;

 bool flag = false;

 void Towers(int n,char a,char b,char c, int i);

 

 

 

 int main() {

     int n, i;

     cin >> n >> i;

     Towers(n,'1','2','3', i);

     cout << "\n";

     return 0;

 }

 

 void Towers(int n,char a,char b,char c, int i){

     if(n==1){

         if (flag == true){

             return;

         }

         if (count2 == i-1){

             cout<<"move "<

             flag = true;

         }

         count2++;

     }

     else{

         if (flag == true){

             return;

         }

         Towers(n-1,a,c,b, i);

         if (count2 == i-1){

             cout<<"move "<

             flag = true;

         }

         count2++;

         Towers(n-1,b,a,c, i);

         

     }

 }

 

#12: 5% TLE (1s)

Killed

這題當然不能直接模擬,肯定TLE。
分析
第 i 次移動的規則:如果 i 在 前半部分 (2^(n-1)),則第 i 次移動來自搬動 n-1 個盤子的過程,也就是從 1=>2 先進行的步驟。
如果 i 剛好是 第 2^(n-1) 次移動,則我們搬動 n 號盤子。
否則,i 在 後半部分 (2^(n-1) + 1 之後),則它來自搬動 n-1 個盤子的第二段過程,這時 i 需要相對應地減去 2^(n-1),繼續計算剩餘的步驟。

完整程式:

#include <iostream>
#include <cstdio> // 提升輸出速度

using namespace std;

// 直接計算第 i 次移動是誰
void findMove(int n, long long i, char a, char b, char c) {
    if (n == 1) {
        printf("move 1 from %c to %c\n", a, c);
        return;
    }

    long long half = (1LL << (n - 1)); // 2^(n-1)

    if (i < half) {
        findMove(n - 1, i, a, c, b); // i 在前半部分
    } else if (i == half) {
        printf("move %d from %c to %c\n", n, a, c); // 搬動最大的盤子
    } else {
        findMove(n - 1, i - half, b, a, c); // i 在後半部分
    }
}

int main() {
    int n;
    long long i;
    cin >> n >> i;
    findMove(n, i, '1', '2', '3');
    return 0;
}

 
ZeroJudge Forum