Zerojudge g877

首次架設靜態網站,如有疏失,還請多多包涵。歡迎來信zhuastor@gmail.com

解題心得

這題還蠻好玩的,推規律推了一個小時多,然後還吃了11個NA哈哈,不知道正解,僅供參考。我的解法細節部分要注意。

解題想法

當箱子數量為偶數,永遠不會有社長與員工將跳同樣箱子的情況,而奇數時則有,我首先針對n=3、5、7進行模擬(對我沒有去想1然後就卡了好幾次NA),找到每次相遇的位置是有規律的。
它的規律很有趣,先觀察他前幾次的相遇位置(等於社長位置!),第一次會在第中間箱子,第二次則在第1箱子。
First:mid => Second:left => Third:mid+1 => Forth:left+1 =>… Last:right(變數設定:left為1,mid為(n/2)+1,right為n)
當社長到達right,此時上一個循環結束了,但也是新循環的開始,因此在變數操作上需要注意。
想到此時,我發現只需要將目光放在社長身上,員工的位置可以從社長的位置直接得到,問題更簡單了。
(Ps : code內註解的”相遇”,就是社長與員工即將跳同樣箱子時的情況。)

AC code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll int t,n,k;
int main(){
    cin >> t;
    while(t--){
        cin >> n >> k;
        if(n%2==0){
            if(k%n==0)cout << n << endl;
            else cout << k%n << endl;
        }
        else if(n==1)cout << 1 << endl;
        else if(n==3){//直接加一個條件,嘿嘿以防萬一
            if(k%3==0)cout << 2 << endl;
            else if(k%3==1)cout << 1 << endl;
            else cout << 3 << endl;
        }
        else{
            if(k>=((n-1)*(n/2)+((n/2)+1))){//這一串是我推出的循環次數
                k%=((n-1)*(n/2)+((n/2)+1)-1);//扣掉循環,這裡有點細節,要弄懂還是自己推推看吧!
            }
            // cout << k << endl;
            if(k>=((n/2)+1)){//第一次相遇
                int step=(n/2)+1+1;//員工的位置
                //此時fir碰到,sec是在起點碰到
                k-=((n/2)+1);
                int now=2;//下一次碰到的模式 1 or 2
                int rec=1;
                //rec是隨著模式改變的碰到位置,if now==2 => step=rec+1且rec++ 
                //else now==1 => step=(rec+n/2)+1此時rec不變化 
                while(k>=(n/2)){//相遇
                    if(now==2){
                        now=1;
                        k-=(n/2);
                        step=rec+1;
                        rec++;
                    }
                    else{//now==1
                        now=2;
                        k-=(n/2);
                        step=rec+(n/2)+1;
                        //rec不變化
                    }
                }
                step+=k;
                if(step>n)step%=n;
                cout << step << endl;
            }
            else{
                cout << k << endl;
            }
        }
    }
    return 0;
}

題目連結 : 板中資訊APCS班程式挑戰賽