網(wǎng)站鏈接:騰訊前端攻略。本來早就有的了,但是自己一直很排斥任何有關(guān)做題闖關(guān)的,今天又不小心看到了于是試了一下發(fā)現(xiàn)非常有意思,考察前端的基礎(chǔ)知識,很靈活,比發(fā)試卷那種做題方式有意思多了,還能鞏固或提升自己的能力
第一關(guān),抓包
提示要抓包,于是查看在chrome查看response header,提示說『請設(shè)置隱藏域的值』,于是查了下網(wǎng)頁的html代碼,發(fā)現(xiàn)有一個隱藏域
<input type="hidden" name="timestamp">
于是猜測是要設(shè)置timestamp的值,就用Javascript在Chrome控制臺中試了一下,果然對了:)
document.getElementsByName('timestamp').value = new Date().getTime()
第二關(guān),CSS繪圖
考察用CSS繪制簡單的橢圓、三角形。就是考察對border和border-radius的理解以及會用css3中的旋轉(zhuǎn),沒什么可說的,查看w3schools上的文檔。不過需要注意的是題目中三角形指出了一定要繞某個點旋轉(zhuǎn),所以必須指定transform-origin
// 橢圓
border-radius: 50%;
// 三角形
border-color: transparent black;
-webkit-transform-origin: top right;
-webkit-transform: rotate(-60deg);
第三關(guān),坦克大戰(zhàn)
這個。。。涉及到游戲,真的是沒有興趣也壓根不會,所以果斷去網(wǎng)上找了一個代碼,涉及到版權(quán),就不貼出來了。。。
第四關(guān),JS基礎(chǔ)
第四題是最簡單的一道,就是javascript的一些基本的使用方法,也就是語法,分三道題全是填空,下面<>表示要填的空
/* 1. 數(shù)組克?。〝?shù)組元素非引用類型) */
var clone = function(arr){
return <>
};
// 答案:arr.slice()
/* 2. 去除字符串首尾空格 */
var trim = function(s){
return <>
};
// 答案:s.trim()
/* 3. 將Nodelist對象轉(zhuǎn)換為數(shù)組對象 */
var arrify = function(list){
return <>
};
// 答案:Array.prototype.slice.call(list)
第五關(guān),求最大值
這是最有意思的一個題,綜合了DOM操作、算法方面的知識。用動態(tài)規(guī)劃,由于是求最值,設(shè)
r[i][j]為第0層到第i層的第j個節(jié)點的數(shù)字和的最大值(i和j均從0開始計數(shù)),data[i][j]為第i行j列的數(shù)字值,則
r[i][j] = max(r[i-1][j-1], r[i-1][j]) + data[i][j] // i > 0, i > j > 0,
r[i][j] = r[i-1][0] + data[i][j] // i > 0, j = 0
r[i][j] = r[i-1][i-1] + data[i][j] // i > 0, j = i
然后為了輸出路徑,倒序遍歷r數(shù)組,倒序輸出節(jié)點,并在圖中選中節(jié)點。為了方便,引入jquery,方便對DOM樹的操作。時間空間復(fù)雜度均為O(N),N是節(jié)點數(shù),如果不是因為要自動選中圖中的節(jié)點,而選中節(jié)點是又必須是從第二層開始依次序逐層選中的話,空間復(fù)雜度可以是O(n),n為最后一層的節(jié)點數(shù)。以下是代碼實現(xiàn)
// 引入jquery,以便使用jquery操作DOM。貼代碼是要先貼這一段再貼其他的,以免jquery庫還未加載完畢
var s = document.createElement('script');
s.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js";
document.body.appendChild(s);
var record = [[+$($('#box>div>span')[0]).text()]];
var $rows = $('#box>div');
// 行
for (var i = 1; i < $rows.length; i++) {
var row = $rows[i]
var $cols = $(row).children('span')
record.push([])
// 列
for (var j = 0; j < $cols.length; j++) {
var num = +$($cols[j]).text()
switch (j) {
case 0: record[i][j] = record[i-1][0] + num;break;
case i: record[i][j] = record[i-1][i-1] + num;break;
default: record[i][j] = Math.max(record[i-1][j-1], record[i-1][j]) + num;
}
}
}
// 找到產(chǎn)生最大值的路徑中最深層次的節(jié)點的下標
var max = 0
for (var k = 1; k < record[i-1].length; k++) {
if (record[i-1][k] > record[i-1][max]) {
max = k
}
}
var path = []
// 從第一層節(jié)點到當前層節(jié)點數(shù)字之和的最大值
var sum = record[i-1][max]
// 從倒數(shù)第二層開始往回遍歷,倒序輸出路徑
for (var i = record.length-1; i--;) {
var r = record[i]
var a = max ? r[max-1] : -1
var b = (max == i+1) ? -1 : r[max]
var t = max
// 最大值路徑在當前層中的節(jié)點下標
if (a > b) {
max--;
}
// 實際存的是上一層的節(jié)點
path.push([t, sum - r[max]])
sum = r[max]
}
// 選中圖中的節(jié)點
for (var i = 2; $rows.length; i++) {
var node = path.pop()
$($('#box').children('#row_' + i).children()[node[0]]).click()
console.log('%d -> %d', i, node[1])
}