首次架設靜態網站,如有疏失,還請多多包涵。歡迎來信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班程式挑戰賽