NodeJs洗牌演算法
阿新 • • 發佈:2019-01-10
網易有道2017內推程式設計題
洗牌在生活中十分常見,現在需要寫一個程式模擬洗牌的過程。 現在需要洗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次之後從上往下的序列。
輸入描述:
第一行一個數T(T ≤ 100),表示資料組數。對於每組資料,第一行兩個數n,k(1 ≤ n,k ≤ 100),接下來一行有2n個數a1,a2,…,a2n(1 ≤ ai ≤ 1000000000)。表示原始牌組從上到下的序列。
輸出描述:
對於每組資料,輸出一行,最終的序列。數字之間用空格隔開,不要在行末輸出多餘的空格。
輸入例子:
3
3 1
1 2 3 4 5 6
3 2
1 2 3 4 5 6
2 2
1 1 1 1
輸出例子:
1 4 2 5 3 6
1 5 4 3 2 6
1 1 1 1
以下是node實現:
process.stdin.setEncoding('utf8');
var count=0;
var data='',chunk='';
var i=0,len=0;
process.stdin.on('readable', () => {
chunk = process.stdin.read();
if(typeof chunk === 'string'){
data+=chunk.trim()+',';
}
if(data!==''){
count=data.split(',')[0];
if(i>parseInt(count)*2 ){
process.stdin.emit('end');
return;
}
}
i++;
});
//數字翻轉
function rev(str){
var strLen=str.length;
var s='',k=0;
for(k=strLen;k>=0;k--){
s+=str.charAt(k);
}
return s;
}
function DiGui(n,p,m){
var x,y=0,result='';
var array=new Array();
var mm=m;
for(x=n-1,y=2*n-1;x>=0;x--,y--){
yx=p[y].toString()+p[x].toString();
array.push(yx);
}
array=(array+'').replace(/((\d)(\d))+/g,'$2,$3');
mm=mm-1;
//遞迴
if(mm>=1){
result=DiGui(n,array.split(','),mm);
}
else{
result=array;
}
return rev(result);
}
process.stdin.on('end', () => {
data=data.split(',');//變成陣列
len=data.length-2;//得到所有輸入陣列長度
for(var j=1;j<len;j=j+2){
var q=data[j].split(' ')
var n=q[0];//多少數字的一半
var m=q[1];//洗牌多少次
var p=data[j+1].split(' ');//將需要洗牌的數字轉變成陣列
var pLen=p.length-1;
var re=DiGui(n,p,m).split(',').join(' ');
console.log("輸出:"+re);
}
process.stdout.write('end');
});