解题思路

这是一道贪心算法题目,主要思路如下:

  1. 问题分析:

    • 每一步都可以选择东南西北四个方向
    • 每个方向都有对应的体力消耗
    • 需要走出
    • 目标是最小化总体力消耗
  2. 贪心策略:

    • 对于每一步,选择四个方向中体力消耗最小的方向
    • 当多个方向体力值相同时,按东南西北顺序优先选择
    • 记录每一步的选择方向和累计体力消耗
  3. 输出要求:

    • 第一行输出最小总体力值
    • 第二行输出行走方案,用ESWN表示方向

代码

#include <iostream>
using namespace std;

const int MAXN = 1000000;
int costs[MAXN][4];  // 存储每步各方向的体力消耗
char path[MAXN];     // 存储行走路径

int main() {
    int T;
    cin >> T;
    
    while(T--) {
        int n;
        cin >> n;
        
        // 读入每步四个方向的体力消耗
        for(int j = 0; j < 4; j++) {
            for(int i = 0; i < n; i++) {
                cin >> costs[i][j];
            }
        }
        
        // 贪心选择每一步的方向
        int totalCost = 0;
        for(int i = 0; i < n; i++) {
            int minCost = costs[i][0];
            char dir = 'E';
            
            // 检查南方向
            if(costs[i][1] < minCost) {
                minCost = costs[i][1];
                dir = 'S';
            }
            // 检查西方向
            if(costs[i][2] < minCost) {
                minCost = costs[i][2];
                dir = 'W';
            }
            // 检查北方向
            if(costs[i][3] < minCost) {
                minCost = costs[i][3];
                dir = 'N';
            }
            
            totalCost += minCost;
            path[i] = dir;
        }
        
        // 输出结果
        cout << totalCost << endl;
        for(int i = 0; i < n; i++) {
            cout << path[i];
        }
        cout << endl;
    }
    return 0;
}
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        
        while(T-- > 0) {
            int n = sc.nextInt();
            int[][] costs = new int[n][4];
            
            // 读入每步四个方向的体力消耗
            for(int j = 0; j < 4; j++) {
                for(int i = 0; i < n; i++) {
                    costs[i][j] = sc.nextInt();
                }
            }
            
            // 贪心选择每一步的方向
            int totalCost = 0;
            StringBuilder path = new StringBuilder();
            
            for(int i = 0; i < n; i++) {
                int minCost = costs[i][0];
                char dir = 'E';
                
                // 检查南方向
                if(costs[i][1] < minCost) {
                    minCost = costs[i][1];
                    dir = 'S';
                }
                // 检查西方向
                if(costs[i][2] < minCost) {
                    minCost = costs[i][2];
                    dir = 'W';
                }
                // 检查北方向
                if(costs[i][3] < minCost) {
                    minCost = costs[i][3];
                    dir = 'N';
                }
                
                totalCost += minCost;
                path.append(dir);
            }
            
            // 输出结果
            System.out.println(totalCost);
            System.out.println(path.toString());
        }
    }
}
def solve_case():
    n = int(input())
    costs = [[] for _ in range(n)]
    
    # 读入每步四个方向的体力消耗
    for j in range(4):
        row = list(map(int, input().split()))
        for i in range(n):
            costs[i].append(row[i])
    
    # 贪心选择每一步的方向
    total_cost = 0
    path = []
    directions = ['E', 'S', 'W', 'N']
    
    for i in range(n):
        min_cost = float('inf')
        best_dir = 'E'
        
        # 检查四个方向
        for j, dir in enumerate(directions):
            if costs[i][j] < min_cost:
                min_cost = costs[i][j]
                best_dir = dir
        
        total_cost += min_cost
        path.append(best_dir)
    
    # 输出结果
    print(total_cost)
    print(''.join(path))

def main():
    T = int(input())
    for _ in range(T):
        solve_case()

if __name__ == "__main__":
    main()

算法及复杂度

  • 算法:贪心算法
  • 时间复杂度: - 其中 为测试用例数, 为步数
  • 空间复杂度: - 需要存储路径