1 条题解

  • 0
    @ 2025-5-26 21:33:53

    题目分析

    本题需计算国际象棋中王、后、车、象的最少步数。各棋子走法规则如下:

    • :横竖斜走,每次一格,步数为行差与列差的最大值。
    • :横竖斜走,步数不限。同行、同列、同斜线(行差=列差)时一步,否则两步(不同行、列、斜线时,后可分两步横竖走到达)。
    • :横竖走,步数不限。同行或同列时一步,否则不可达(输出InfInf,因车不能斜走,不同行且不同列时无法到达)。
    • :斜走,步数不限。行差=列差时一步;行差与列差同奇偶(且不等)时两步;奇偶不同时不可达(象只能走同色格子,行差列差奇偶不同则格子颜色不同,无法到达)。

    方法思路

    1. 坐标转换:将字母(列)和数字(行)转换为行差dxdx(数字差)和列差dydy(字母差)。
    2. 分情况计算步数
      • :直接取dxdxdydy的最大值。
      • :判断是否同行、同列或同斜线,决定步数1122
      • :判断是否同行或同列,决定步数11或不可达(InfInf)。
      • :判断行差列差的关系(是否相等、奇偶性),决定步数1122或不可达(InfInf)。

    解决代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    #define MAX(x, y) (((x) > (y)) ? (x) : (y))
    
    int main(void) {
        int t;
        scanf("%d", &t);
        while (t--) {
            char start[3], end[3];
            scanf("%s%s", start, end);
            
            int dx = abs(end[1] - start[1]); // 行差(数字部分,如 '1'和'3'的差为2)
            int dy = abs(end[0] - start[0]); // 列差(字母部分,如 'a'和'c'的差为2)
            
            int kcnt, qcnt, rcnt, bcnt;
            
            if (dx == 0 && dy == 0) {
                kcnt = qcnt = rcnt = bcnt = 0;
            } else {
                kcnt = MAX(dx, dy); // 王的步数
                
                // 后的步数:同线(行、列、斜线)一步,否则两步
                qcnt = (dx == dy || dx == 0 || dy == 0) ? 1 : 2;
                
                // 车的步数:同行(dx=0)或同列(dy=0)一步,否则不可达
                rcnt = (dx == 0 || dy == 0) ? 1 : -1;
                
                // 象的步数:dx==dy→1;同奇偶(≠0)→2;否则不可达
                if (dx == dy) {
                    bcnt = 1;
                } else if (abs(dx - dy) % 2 != 0) {
                    bcnt = -1; // 奇偶不同,不可达
                } else {
                    bcnt = 2; // 同奇偶,且不等,两步
                }
            }
            
            printf("%d %d ", kcnt, qcnt);
            if (rcnt == -1) {
                printf("Inf ");
            } else {
                printf("%d ", rcnt);
            }
            if (bcnt == -1) {
                printf("Inf\n");
            } else {
                printf("%d\n", bcnt);
            }
        }
        return 0;
    }
    

    代码解释

    1. 输入处理:读取测试用例数和每组的起始、目标位置,转换为行差dxdx和列差dydy
    2. 步数计算
      • MAX(dx,dy)MAX(dx, dy)直接计算步数。
      • :通过判断行、列、斜线关系确定步数(1122)。
      • :仅同行或同列时可达(步数11),否则不可达(InfInf)。
      • :根据行差列差的奇偶性和是否相等,确定步数(121、2InfInf)。
    3. 输出处理:按格式输出各棋子的步数,不可达时输出InfInf

    复杂度分析

    每组数据处理时间为O(1)O(1),总时间复杂度O(t)O(t),高效处理输入规模(t20t \leq 20)。

    • 1

    信息

    ID
    658
    时间
    1000ms
    内存
    256MiB
    难度
    6
    标签
    递交数
    1
    已通过
    1
    上传者