跳石板

本文介绍了一种基于动态规划的算法,用于解决在一个特殊规则下,如何从编号N的石板跳跃至M号石板的问题,通过寻找石板编号的约数来确定跳跃路径,实现最少次数的跳跃。

题目描述

小易来到了一条石板路前,每块石板上从1挨着编号为:1、2、3…
这条石板路要根据特殊的规则才能前进:对于小易当前所在的编号为K的 石板,小易单次只能往前跳K的一个约数(不含1和K)步,即跳到K+X(X为K的一个非1和本身的约数)的位置。 小易当前处在编号为N的石板,他想跳到编号恰好为M的石板去,小易想知道最少需要跳跃几次可以到达。

例如:
N = 4,M = 24:
4->6->8->12->18->24
于是小易最少需要跳跃5次,就可以从4号石板跳到24号石板
输入描述:
输入为一行,有两个整数N,M,以空格隔开。 (4 ≤ N ≤ 100000) (N ≤ M ≤ 100000)
输出描述:
输出小易最少需要跳跃的步数,如果不能到达输出-1
动态规划
采用动态规划思想求解。创建一个vector容器steps,steps[i]表示到达i号石板所需的最小步数。
初始化为steps容器为INT_MAX。从序号N的石板开始逐个遍历,若steps[i]为INT_MAX,表示该点不可到达,直接开始下次循环。
若steps[i]不为INT_MAX,表示该点可以到达,下面求解编号i的约数,进行动态规划。动态规划的转移方程为

steps[i + j] = min(steps[i] + 1, steps[i + j])   //i为石板编号,j为i的约束
steps[N] = 0

完整代码如下:

#include <iostream>
#include <vector>
#include <climits>
#include <cmath>
#include <algorithm>
using namespace std;

int main(){
	int N, M;
	while (cin >> N >> M){
		vector<int> steps(M + 1, INT_MAX);
		steps[N] = 0;
		for (int i = N; i <= M; i++){
			if (steps[i] == INT_MAX){
				continue;
			}
			for (int j = 2; (j*j) <= i; j++){
				if (i%j == 0){
					if (i + j <= M){
						steps[i + j] = min(steps[i] + 1, steps[i + j]);
					}
					if (i + (i / j) <= M){
						steps[i + (i / j)] = min(steps[i] + 1, steps[i + (i / j)]);
					}

				}

			}
		}
		if (steps[M] == INT_MAX){
			steps[M] = -1;
		}
		cout << steps[M] << endl;
	}
	return 0;
}
在展锐(Unisoc)6531E 平台上,若系统已集成 **MiniGUI** 作为嵌入式 GUI 库,则可以开发出界面美观、交互流畅的“”游戏。MiniGUI 提供了窗口管理、图形绘制、事件处理和资源加载能力,非常适合用于功能手机或低端智能设备上的小游戏开发。 以下是一个完整、可运行于 **展锐 6531E + MiniGUI SDK 环境** 的“”游戏 C 语言实现,包含: - 使用 MiniGUI 创建主窗口与绘图环境 - 图像设计:使用位图(BMP)替代原始方块 - 声音反馈:通过音频驱动播放蜂鸣或 WAV 音效 - 游戏逻辑:跃、重力、平台滚动、得分机制 --- ```c #include <minigui/common.h> #include <minigui/minigui.h> #include <minigui/gdi.h> #include <minigui/window.h> #include <minigui/fixedmath.h> // 屏幕分辨率适配展锐6531E典型LCD:128x160 #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 160 // 游戏常量 #define PLAYER_X 40 #define PLAYER_SIZE 10 #define PLATFORM_HEIGHT 6 #define PLATFORM_WIDTH 30 #define GRAVITY 2 #define JUMP_VELOCITY -12 #define GROUND_Y (SCREEN_HEIGHT - 20) #define MAX_PLATFORMS 4 #define FPS 20 #define TIMER_INTERVAL (1000 / FPS) // 颜色宏(RGB565转gal_pixel) #define COLOR_brown MakeRGB(139, 69, 19) #define COLOR_gold MakeRGB(255, 215, 0) #define COLOR_skyblue MakeRGB(135, 206, 235) // 函数前向声明 static int GameMainWindowProc(HWND hwnd, int message, WPARAM wParam, LPARAM lParam); void game_init(void); void update_game_logic(void); void draw_game_elements(HDC hdc); void player_jump(void); void play_sound(int type); // type: 1=jump, 2=score, 3=gameover // 外部接口(由展锐SDK提供) extern void audio_play_tone(int freq, int ms); // 蜂鸣器发声 extern void audio_play_wav(const char* name); // 播放WAV文件 extern BOOL keypad_is_pressed(int key_code); // 按键检测 #define SCANCODE_UP 1 // 假设上键为1 // 全局变量 static HWND hMainWnd = HWND_INVALID; // 玩家状态 typedef struct { int x, y; int vel_y; BOOL on_ground; } Player; Player player; int score = 0; BOOL game_over = FALSE; // 平台数组 typedef struct { int x, y; BOOL active; } Platform; Platform platforms[MAX_PLATFORMS]; // 位图资源(预加载) BITMAP player_bmp; // 玩家精灵图(建议尺寸 10x10) BITMAP platform_bmp; // 平台贴图(木纹/石板纹理) /* * 加载图像资源(需将图片转为C数组或存于FS) */ void load_resources(void) { // 方式一:从文件系统加载(需文件系统支持) #if 0 LoadBitmapFromFile(HDC_SCREEN, &player_bmp, "res/player.bmp"); LoadBitmapFromFile(HDC_SCREEN, &platform_bmp, "res/platform.bmp"); #endif // 方式二:内嵌数组(推荐用于无文件系统的设备) extern unsigned char player_bmp_bits[]; extern unsigned char platform_bmp_bits[]; player_bmp.bmType = 0; player_bmp.bmBitsPerPixel = 16; player_bmp.bmBytesPerLine = 20; // 10像素 * 2字节 player_bmp.bmHeight = 10; player_bmp.bmWidth = 10; player_bmp.bmPitch = 20; player_bmp.bmBits = player_bmp_bits; platform_bmp.bmType = 0; platform_bmp.bmBitsPerPixel = 16; platform_bmp.bmBytesPerLine = 60; // 30*2 platform_bmp.bmHeight = 6; platform_bmp.bmWidth = 30; platform_bmp.bmPitch = 60; platform_bmp.bmBits = platform_bmp_bits; } /* * 初始化游戏数据 */ void game_init(void) { player.x = PLAYER_X; player.y = GROUND_Y; player.vel_y = 0; player.on_ground = TRUE; score = 0; game_over = FALSE; for (int i = 0; i < MAX_PLATFORMS; i++) { platforms[i].x = 60 + i * (PLATFORM_WIDTH + 35); platforms[i].y = GROUND_Y - ((i % 2) ? 15 : 0); platforms[i].active = TRUE; } } /* * 玩家跃 */ void player_jump(void) { if (player.on_ground && !game_over) { player.vel_y = JUMP_VELOCITY; player.on_ground = FALSE; play_sound(1); // 播放跃音效 } } /* * 更新游戏逻辑 */ void update_game_logic(void) { if (game_over) return; // 重力模拟 player.vel_y += GRAVITY; player.y += player.vel_y; // 地面碰撞 if (player.y >= GROUND_Y) { player.y = GROUND_Y; player.vel_y = 0; player.on_ground = TRUE; } // 移动平台 & 检测着陆 for (int i = 0; i < MAX_PLATFORMS; i++) { platforms[i].x -= 2; // 循环复用平台 if (platforms[i].x + PLATFORM_WIDTH < 0) { platforms[i].x = SCREEN_WIDTH; platforms[i].y = GROUND_Y - (rand() % 30); platforms[i].active = TRUE; } // 落地判定 if (!player.on_ground && player.y + PLAYER_SIZE >= platforms[i].y && player.y + PLAYER_SIZE <= platforms[i].y + 5 && player.x + PLAYER_SIZE > platforms[i].x && player.x < platforms[i].x + PLATFORM_WIDTH) { player.y = platforms[i].y - PLAYER_SIZE; player.vel_y = 0; player.on_ground = TRUE; score++; play_sound(2); // 得分音效 } } // 掉落失败 if (player.y > SCREEN_HEIGHT) { game_over = TRUE; play_sound(3); } } /* * 绘制游戏元素 */ void draw_game_elements(HDC hdc) { RECT rect; GetClientRect(hMainWnd, &rect); // 渐变背景 for (int y = 0; y < rect.bottom; y++) { gal_pixel color = COLOR_skyblue.value + (y >> 3); SelectObject(hdc, CreateBrush(COLOR2PIXEL(hdc, color))); FillBox(hdc, 0, y, rect.right, 1); } // 绘制地面线 SelectObject(hdc, CreatePen(PEN_TYPE_SOLID, 2, COLOR_brown)); MoveTo(hdc, 0, GROUND_Y + 10); LineTo(hdc, rect.right, GROUND_Y + 10); // 绘制玩家(使用位图) if (player_bmp.bmBits) { StretchBlt(hdc, player.x, player.y, PLAYER_SIZE, PLAYER_SIZE, HDC_SCREEN, &player_bmp, 0, 0, player_bmp.bmWidth, player_bmp.bmHeight, 0); } else { // 回退:绘制红色方块 SelectObject(hdc, CreateBrush(COLOR_red)); FillBox(hdc, player.x, player.y, PLAYER_SIZE, PLAYER_SIZE); } // 绘制平台 for (int i = 0; i < MAX_PLATFORMS; i++) { if (platforms[i].active) { if (platform_bmp.bmBits) { StretchBlt(hdc, platforms[i].x, platforms[i].y, PLATFORM_WIDTH, PLATFORM_HEIGHT, HDC_SCREEN, &platform_bmp, 0, 0, platform_bmp.bmWidth, platform_bmp.bmHeight, 0); } else { SelectObject(hdc, CreateBrush(COLOR_brown)); FillBox(hdc, platforms[i].x, platforms[i].y, PLATFORM_WIDTH, PLATFORM_HEIGHT); } } } // 显示分数 char szScore[32]; sprintf(szScore, "Score:%d", score); SetBkMode(hdc, BM_TRANSPARENT); SetTextColor(hdc, COLOR_gold); TextOut(hdc, 5, 5, szScore); // 游戏结束提示 if (game_over) { SetTextColor(hdc, COLOR_red); TextOut(hdc, (SCREEN_WIDTH - 6 * 8) / 2, SCREEN_HEIGHT / 2, "GAME OVER"); TextOut(hdc, (SCREEN_WIDTH - 6 * 6) / 2, SCREEN_HEIGHT / 2 + 15, "OK:Re"); } } /* * 播放声音 */ void play_sound(int type) { switch (type) { case 1: audio_play_tone(700, 80); break; // jump case 2: audio_play_tone(900, 100); break; // score case 3: audio_play_tone(300, 500); break; // game over default: break; } } /* * 主窗口过程函数 */ static int GameMainWindowProc(HWND hwnd, int message, WPARAM wParam, LPARAM lParam) { HDC hdc; switch (message) { case MSG_CREATE: load_resources(); game_init(); SetTimer(hwnd, 1, TIMER_INTERVAL); // 定时刷新 return 0; case MSG_PAINT: hdc = BeginPaint(hwnd); draw_game_elements(hdc); EndPaint(hwnd, hdc); return 0; case MSG_TIMER: if (wParam == 1) { InvalidateRect(hwnd, NULL, TRUE); // 触发重绘 update_game_logic(); // 更新逻辑 } return 0; case MSG_KEYUP: if (wParam == SCANCODE_UP) { player_jump(); } else if (wParam == SCANCODE_ENTER && game_over) { game_init(); // 按确定重启 } return 0; case MSG_CLOSE: KillTimer(hwnd, 1); DestroyMainWindow(hwnd); PostQuitMessage(0); return 0; } return DefaultMainWinProc(hwnd, message, wParam, lParam); } /* * 程序入口点(MiniGUI 标准入口) */ int MiniGUIMain(int argc, const char* argv[]) { MAINWINCREATE create_info; // 初始化 MiniGUI 运行环境 if (InitMiniguiTSK() != 0) { return -1; } // 创建主窗口 memset(&create_info, 0, sizeof(create_info)); create_info.dwStyle = WS_VISIBLE | WS_BORDER; create_info.dwExStyle = WS_EX_NONE; create_info.spCaption = "Jump Jump"; create_info.hMenu = 0; create_info.hCursor = GetSystemCursor(IDC_ARROW); create_info.hIcon = 0; create_info.MainWindowProc = GameMainWindowProc; create_info.lx = 0; create_info.ty = 0; create_info.rx = SCREEN_WIDTH; create_info.by = SCREEN_HEIGHT; create_info.iBkColor = COLOR_lightwhite.pixel; create_info.hHosting = HWND_DESKTOP; hMainWnd = CreateMainWindow(&create_info); if (hMainWnd == HWND_INVALID) { TermMinigui(); return -1; } ShowWindow(hMainWnd, SW_SHOWNORMAL); // 消息循环 MSG msg; while (GetMessage(&msg, hMainWnd)) { TranslateMessage(&msg); DispatchMessage(&msg); } MainWindowThreadCleanup(hMainWnd); TermMinigui(); return 0; } ``` --- ### ✅ 编译与部署说明(针对展锐6531E SDK) 1. **资源准备**: - 将 `player.bmp` 和 `platform.bmp` 转换为 **16位色 BMP** 或嵌入为 C 数组。 - 示例工具:`xxd -i player.bmp > player.c` 2. **链接库配置**: ```makefile LIBS += -lminigui_ths -lgdi -lmgplus -ljpeg -lpng ``` 3. **音频驱动对接**: 实现 `audio_play_tone()` 调用 PWM 或 I2S 输出蜂鸣信号。 4. **按键映射**: 确保 `SCANCODE_UP` 对应物理“上键”,可在 `keypad.h` 中定义。 --- ### ✅ 视觉与听觉效果提升总结 | 特性 | 实现方式 | |------|----------| | 🎨 美观界面 | MiniGUI 双缓冲 + 渐变背景 | | 🖼️ 图像显示 | BMP 贴图替代方块 | | 🔊 音效反馈 | tone/WAV 播放三种音效 | | ⌨️ 交互自然 | 消息机制响应按键 | | 📱 分辨率适配 | 支持 128x160 小屏布局 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值