第一題:
洗牌在生活中十分常見,現在需要寫一個程序模擬洗牌的過程。現在需要洗2n張牌,從上到下依次是第1張,第2張,第3張一直到第2n張。首先,我們把這2n張牌分成兩堆,左手拿着第1張到第n張(上半堆),右手拿着第n+1張到第2n張(下半堆)。接着就開始洗牌的過程,先放下右手的最後一張牌,再放下左手的最後一張牌,接着放下右手的倒數第二張牌,再放下左手的倒數第二張牌,直到最後放下左手的第一張牌。接着把牌合併起來就可以了。例如有6張牌,最開始牌的序列是1,2,3,4,5,6。首先分成兩組,左手拿着1,2,3;右手拿着4,5,6。在洗牌過程中按順序放下了6,3,5,2,4,1。把這六張牌再次合成一組牌之後,我們按照從上往下的順序看這組牌,就變成了序列1,4,2,5,3,6。 現在給出一個原始牌組,請輸出這副牌洗牌k次之後從上往下的序列。
//觀察可發現,執行k次後,數x的下標i(0<=i<2n)會變成i*pow(2,k)%(2n-1)。
//但是k取值範圍在1~100之間,使用pow(2,k)函數返回值會溢出。
//因此可以考慮用for循環執行k次
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int T;
cin>>T;
while(T>0)
{
int n ,k;
cin>>n>>k;
vector<int>data(2*n,0);
for(int i = 0; i < 2*n ; i ++)
{
cin>>data[i];
}
for(int j = 0 ; j < k ; j ++)
{
vector<int>mData=data;
for(int i = 0 ; i < n ; i ++)
{
data[2*i] = mData[i];
data[2*i+1] = mData[i+n];
}
}
for(int i = 0 ; i < data.size()-1;i++)
cout<<data[i]<<" ";
cout<<data[2*n-1]<<endl;
T --;
}
}
第二題:構造隊列
//從隊尾開始逆推,一步步還原原來的模樣。不是很難
#include<deque>
#include<iostream>
using namespace std;
int main()
{
int T;
cin>>T;
while(T>0)
{
int num;
cin>>num;
deque<int>que;
for(int i = num ; i > 0 ; i --)
{
que.push_front(i);
int x = que.back();
que.pop_back();
que.push_front(x);
}
for(int i = 0 ; i < que.size()-1 ; i ++)
{
cout<<que[i]<<" ";
}
cout<<que[que.size()-1]<<endl;
T--;
}
return 0;
}