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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/3/21 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MoeCTF 2021Re部分------Algorithm_revenge 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • ida分析
    • 腳本分析
      • 生成map地圖
      • 數據累加
      • 提醒:絕對不是取出每行最大值相加(特別注意當前元素的上行元素的左中右這個限制),然后把所在列坐標進行存儲
      • 挑出50行最大值列坐標
    • 總結

ida分析


嘗試找最大值

隨機數進行填充地圖,種子是0x1BF52u,而且填充區域是一個三角形。

for ( i = 0; ; ++i ){v3 = i;if ( v3 >= sub_429ED0((__int64)inputs) ) // v3大于長度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個字符,進行判斷跳轉,每次進行數組取值,并且是跨行取值(而且取值的數組范圍行與行之間也是有要求的),也就是取一個列為60,行為50填充地圖值,最后把每行取出來的數和加起來查看最大值。至于input 的值,就是每行中取出值的相對高位置行的方位,也就是我們上面所述數組范圍控制

腳本分析

生成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;

數據累加

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就是想取出數組前一個值和當前值比較大小,

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

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

dp[i][j] += way1;

提醒:絕對不是取出每行最大值相加(特別注意當前元素的上行元素的左中右這個限制),然后把所在列坐標進行存儲

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

這個就是如果上一行取出的值是左(就存j-1),中(就存j),右(就存j+1),注意:上一行取值坐標存放當前行,至于way1和way2這種的話就是根據flag來進行最大值選出。

挑出50行最大值列坐標

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];}

這個aim_arg把最大值的列坐標取出來,列坐標取出來后,然后把pre中的縱坐標值取出

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;}

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

然后輸出ans就行

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

DDDRDDLRLRDRDRLLRRRDLLLRRLDRRDRRLDDDLDRRDLRDLLRDD

總結

  • 主要考算法,而我是小白
  • 總結

    以上是生活随笔為你收集整理的MoeCTF 2021Re部分------Algorithm_revenge的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。