日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

MoeCTF 2021Re部分------Algorithm_revenge

發(fā)布時(shí)間:2025/3/21 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MoeCTF 2021Re部分------Algorithm_revenge 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • ida分析
    • 腳本分析
      • 生成map地圖
      • 數(shù)據(jù)累加
      • 提醒:絕對(duì)不是取出每行最大值相加(特別注意當(dāng)前元素的上行元素的左中右這個(gè)限制),然后把所在列坐標(biāo)進(jìn)行存儲(chǔ)
      • 挑出50行最大值列坐標(biāo)
    • 總結(jié)

ida分析


嘗試找最大值

隨機(jī)數(shù)進(jìn)行填充地圖,種子是0x1BF52u,而且填充區(qū)域是一個(gè)三角形。

for ( i = 0; ; ++i ){v3 = i;if ( v3 >= sub_429ED0((__int64)inputs) ) // v3大于長(zhǎng)度49break;++v18;if ( *(_BYTE *)sub_48F5E0(inputs, i) != 'L'&& *(_BYTE *)sub_48F5E0(inputs, i) != 'R'&& *(_BYTE *)sub_48F5E0(inputs, i) != 'D' ){((void (__fastcall *)(char *))nullsub_2)(&v12);sub_48EF30(v11, "Input ERROR", &v12);sub_401638((__int64)v11);}v5 = *(char *)sub_48F5E0(inputs, i);if ( v5 == 'L' ){--v17;}else if ( v5 == 'R' ){++v17;}if ( v17 <= 0 ){((void (__fastcall *)(char *))nullsub_2)(&v14);sub_48EF30(v13, "Edge ERROR", &v14);sub_401638((__int64)v13);}v16 += dword_4CE040[60 * v18 + v17];}

輸入50個(gè)字符,進(jìn)行判斷跳轉(zhuǎn),每次進(jìn)行數(shù)組取值,并且是跨行取值(而且取值的數(shù)組范圍行與行之間也是有要求的),也就是取一個(gè)列為60,行為50填充地圖值,最后把每行取出來(lái)的數(shù)和加起來(lái)查看最大值。至于input 的值,就是每行中取出值的相對(duì)高位置行的方位,也就是我們上面所述數(shù)組范圍控制

腳本分析

生成map地圖

int dp[60][60]; char pre[60][60]; int n = 50;memset(dp, 0, sizeof(dp));int seed = 114514;srand(seed);for (int i = 1; i <= 50; i++)for (int j = 1; j <= i; j++)dp[i][j] = rand() % 1919810;

數(shù)據(jù)累加

for (int i = 2; i <= n; i++){for (int j = 1; j <= i; j++){int way1 = 0, way2 = dp[i - 1][j], way3 = 0, maxx = 1;if (j - 1 >= 1)way1 = dp[i - 1][j - 1];if (j + 1 <= i)way3 = dp[i - 1][j + 1];if (way2 > way1){way1 = way2;maxx = 2;}if (way3 > way1){way1 = way3;maxx = 3;}if (maxx == 1) pre[i][j] = j - 1;if (maxx == 2) pre[i][j] = j;if (maxx == 3) pre[i][j] = j + 1;dp[i][j] += way1;}}

首先這里需要分別分析一下:

if (j - 1 >= 1)way1 = dp[i - 1][j - 1];

這里的話是j>=2就是想取出數(shù)組前一個(gè)值和當(dāng)前值比較大小,

if (j + 1 <= i)way3 = dp[i - 1][j + 1];

這里的話j <= i-1就是想取出數(shù)組的后一個(gè)值和當(dāng)前值比較大小
總結(jié):
所取值為上行的左中右最大值,加給當(dāng)前行,根據(jù)數(shù)據(jù)范圍限制分別進(jìn)行累加,最后49行根據(jù)各個(gè)不同范圍的和累加到第50行。

dp[i][j] += way1;

提醒:絕對(duì)不是取出每行最大值相加(特別注意當(dāng)前元素的上行元素的左中右這個(gè)限制),然后把所在列坐標(biāo)進(jìn)行存儲(chǔ)

if (maxx == 1) pre[i][j] = j - 1;if (maxx == 2) pre[i][j] = j;if (maxx == 3) pre[i][j] = j + 1;

這個(gè)就是如果上一行取出的值是左(就存j-1),中(就存j),右(就存j+1),注意:上一行取值坐標(biāo)存放當(dāng)前行,至于way1和way2這種的話就是根據(jù)flag來(lái)進(jìn)行最大值選出。

挑出50行最大值列坐標(biāo)

int aim = dp[n][1], aim_arg = 1;string ans;for (int i = 2; i <= n; i++)if (aim < dp[n][i]) {aim_arg = i;aim = dp[n][i];}

這個(gè)aim_arg把最大值的列坐標(biāo)取出來(lái),列坐標(biāo)取出來(lái)后,然后把pre中的縱坐標(biāo)值取出

for (int i = n; i >= 2; i--){int now = pre[i][aim_arg];if (now == aim_arg - 1) ans += 'R';if (now == aim_arg) ans += 'D';if (now == aim_arg + 1) ans += 'L';aim_arg = now;}

這里就根據(jù)下標(biāo)數(shù)組在當(dāng)前行取出上一行的累加列坐標(biāo)值,取出之后進(jìn)行比較,然后得出路徑(從50行到第2行路徑)

然后輸出ans就行

for (int i = (int)ans.size() - 1; i >= 0; i--)cout << ans[i];

DDDRDDLRLRDRDRLLRRRDLLLRRLDRRDRRLDDDLDRRDLRDLLRDD

總結(jié)

  • 主要考算法,而我是小白
  • 總結(jié)

    以上是生活随笔為你收集整理的MoeCTF 2021Re部分------Algorithm_revenge的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。