(File IO): input:swap.in output:swap.out
時間限制: 1000 ms 空間限制: 262144 KB 具體限制
Goto ProblemSet
題目描述
的 頭奶牛站成一排。對於每一個 ,從左往右數第 頭奶牛的編號爲 。 想到了一個新的奶牛晨練方案。他給奶牛們 對整數 ,其中 。他讓她們重複以下包含 個步驟的過程 次:
對於從 到 的每一個步驟i:當前從左往右數在位置 的奶牛序列反轉她們的順序。
當奶牛們重複這一過程 次後,請對每一個 1≤i≤N 輸出從左往右數第 頭奶牛的編號。
輸入
輸入的第一行包含 和 。對於每一個 ,第 行包含 和 ,均爲範圍在 內的整數,其中 Li<Ri。
輸出
在第 行輸出指令序列執行了 次後奶牛序列中從左往右數第 個元素的編號。
樣例輸入
7 2 2
2 5
3 7
樣例輸出
1
2
4
3
5
7
6
數據範圍限制
測試點 滿足。
測試點 滿足 。
測試點 沒有額外限制。
提示
初始時,奶牛們的順序從左往右爲。在這一過程的第一步過後,順序變爲 。在這一過程的第二步過後,順序變爲 。再重複這兩個步驟各一次可以得到樣例的輸出。
解題思路
對於初始的序列 我們可以把它看作數組的位置下標,那麼每次操作不就是調換位置,不用管此時在這個位置上的數,也就是我們只要得出進行 M 次操作後第 位會換到的位置並標記,每一輪結束後就只用調位置就行了,不用再模擬一遍 。
- 拿樣例來解釋:
初始序列爲
先處理出進過 次得出的序列爲
可以得出
上面的數字全都代表數組下標,比如下標上的數變到了下標上
那麼第二輪就是 中,位置上的數不變,
位置上的數到了位置,位置上的數到了位置……
則最後序列就變爲
代碼
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<set>
using namespace std;
int l,r,a[100010],b[100010],c[100010];
int n,m,k;
int main()
{
freopen("swap.in","r",stdin);
freopen("swap.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
a[i]=i;
while(m--){
cin>>l>>r;
for(int i=l;i<=r;i++)
b[i]=a[l+r-i];
for(int i=l;i<=r;i++)
a[i]=b[i];
}
for(int i=1;i<=n;i++){
c[i]=a[i];
a[i]=i;
}
while(k>0){
if(k&1){
for(int i=1;i<=n;i++)
a[i]=c[a[i]];
}
for(int i=1;i<=n;i++)
b[i]=c[c[i]];
for(int i=1;i<=n;i++)
c[i]=b[i];
k/=2;
}
for(int i=1;i<=n;i++)
printf("%d\n",a[i]);
return 0;
}