答案解析5

A、装水

  1. 操作 1:手动加水(需最小化);
  2. 操作 2:移动水(无次数限制,可跨空段移动);
  3. 自动填充:若空单元格i(2≤i≤n-1)左右都有水,会自动填满;
  4. 关键推论:只要存在≥3 个连续的空单元格,仅需 2 次操作 1 就能填满所有空单元格(其余空单元格可通过 "自动填充 + 操作 2 移动水" 覆盖);若不存在≥3 个连续空单元格,则每个空单元格都需手动加 1 次水。
cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
 
int main() {
    int n;
    scanf("%d", &n);
    while (n--) {
        int m;
        scanf("%d", &m);
        char* str = (char*)malloc((m+5) * sizeof(char));
        scanf("%s", str);
 
        int w = 0, count = 0;
        for (int i = 0; i < m-2; i++){
            if (str[i] == '.' && str[i + 1] == '.' && str[i + 2] == '.') {
                w = 1;
                break;
            }   
        }
        for (int i = 0; i < m; i++) if (str[i] == '.')count++;
 
        if (w == 1){
            printf("2\n"); 
            continue;
        }
        else printf("%d\n", count);
    }
     
    return 0;
}

B、签到签到

这个问题的核心是双指针法(夹逼法),利用 "x²+y² 随 x 增大、y 减小的单调性",在 O (√D) 时间复杂度内找到使 | x²+y²-D | 最小的非负整数对 (x,y),避免暴力枚举所有可能的 x、y(暴力枚举会超时,因为 D 最大到 1e12,√D 约 1e6,双指针法效率极高)。

核心原理

对于非负整数 x、y:

  1. x²+y² 的取值范围:最小为 0(x=y=0),最大无界,但我们只需要找到最接近 D 的取值;
  2. 单调性:固定 x 时,y 越大,x²+y² 越大;固定 y 时,x 越大,x²+y² 越大;
  3. 双指针策略:
    • 初始时,x 从 0 开始(最小),y 从√D 开始(最大的可能使 y²≤D 的数);
    • 通过调整 x 和 y 的大小,逐步逼近 "x²+y²=D" 的状态,过程中记录最小差值。
cpp 复制代码
#include<stdio.h>
#include<math.h>
int main() {
    long long D;
    scanf("%lld", &D);
    long long x = 0;
    long long y = (long long)sqrt(D);
    long long min_diff = D;
    while (x <= y) {
        long long cur = x * x + y * y;
        long long diff = cur - D;
        if (diff < 0) {
            diff = -diff;
        }
        if (diff < min_diff) {
            min_diff = diff;
        }
        if (cur > D) {
            y--;
        }
        else {
            x++;
        }
    }
    printf("%lld\n", min_diff);
    return 0;
}

C、热爱物理的zwz

这个问题的核心是利用 "光的全反射对称原理" 推导激光的入射向量,再通过 "最大公约数(GCD)约分" 保证输出向量的最简形式(gcd (i,j,k)=1)。

物理反射原理(核心推导)
  1. 坐标系定义:

    • zwz 位置为原点 (0,0,0),水面是 z=h 的平面(zwz 在水下,距离水面高度为 h,因此水面的 z 坐标是 h);
    • 目标位置为 (x,y,z),激光需先射到水面,经一次全反射后到达目标
  2. 反射的 "镜像法"(关键!):光的反射可等效为 "激光沿直线射向目标的镜像点",镜像点的计算规则:

    • 水面是 z=h,目标点 (x,y,z) 关于水面的镜像点 z 坐标为:h + (h - z) = 2h - z(x、y 坐标不变);
    • 因此,激光的入射向量就是从原点 (0,0,0) 指向镜像点 (x, y, 2h - z) 的向量,即初始向量为(x, y, 2h - z)

    👉 样例验证:样例输入 h=5,目标 (3,3,2) → 镜像点 z 坐标 = 2*5 -2=8 → 初始向量为 (3,3,8)(与样例输出一致,且该向量 gcd=1,无需约分)。

cpp 复制代码
#include<stdio.h>
int main()
{
    int n, a,b,c;
    scanf("%d", &n);
    scanf("%d %d %d", &a,&b,&c);
    int u, uu;
    if (n != 0)
        u = n - c + n;
    else
        u = c;
    if (a < b) {
        uu = a;
    }
    else {
        uu = b;
    }
    if (uu > u) {
        uu = u;
    }
    for (int i = uu; i >= 2; i--) {
        if (a % i == 0 && b % i == 0 && u % i == 0) {
            a = a / i;
            b = b / i;
            u = u / i;
            i++;
        }
    }
    printf("%d %d %d", a, b, u);
    return 0;
}

D、学的太少了,水题凑一下好了

cpp 复制代码
#include<stdio.h>
 
int num(int a, int b) {
    if (b == 0) return a;
    else return num(b, a % b);
}
 
int main() {
    int n, m;
    scanf("%d %d", &n, &m);
    int t = num(n, m);
    printf("%d", t);
}

E、奇怪的等式

这个问题的核心是通过数学公式构造满足条件的整数解 (x,y,z),而非暴力枚举(暴力枚举会因 n 范围大而超时),同时对特殊值(n=0、n=1)直接判定无解。

关键数学推导(构造解的核心)

题目要求找到互不相同的整数 x,y,z,满足:x1​+y1​+z1​=n2​

步骤 1:简化问题,先固定两个变量

我们尝试构造一组通用解,选择x = n(第一个变量),代入等式:n1​+y1​+z1​=n2​化简得:y1​+z1​=n1​

步骤 2:构造 y 和 z 的解

对 y1​+z1​=n1​,我们需要找两个互不相同的整数 y、z,且与 x=n 也互不相同。经典的分数拆分技巧:令 y=n+1(第二个变量),代入得:z1​=n1​−n+11​=n(n+1)(n+1)−n​=n(n+1)1​因此 z=n(n+1)(第三个变量)。

步骤 3:验证构造的解是否满足所有条件

构造的解为:

  • x=n
  • y=n+1
  • z=n(n+1)

验证等式:n1​+n+11​+n(n+1)1​=n(n+1)(n+1)+n+1​=n(n+1)2n+2​=n(n+1)2(n+1)​=n2​完全满足原式!

同时验证 "互不相同":

  • n ≥ 2 时,n <n+1 < n (n+1)(如 n=3 时,3 < 4?不,样例中 n=3 时 y=7?哦,样例是特殊构造,核心逻辑是 "存在通用构造解",样例的解是另一组有效解,代码的构造解是更通用的)。

特殊值判断(n=0、n=1 无解)

  1. n=0:原式右边 02 无意义,直接判定无解;
  2. n=1:代入构造解得 x=1、y=2、z=2,z 与 y 重复(不满足 "互不相同"),且无其他有效解,判定无解;
  3. n≥2:构造的 x=n、y=n+1、z=n (n+1) 互不相同,且满足等式,因此有解。
cpp 复制代码
#include <stdio.h>
int main ()
{
    int n,x,y,z;
    scanf("%d",&n);
     
    x=n;
    y=n+1;
    z=(n+1)*n;
     
    if(n==0||n==1)
    {
        printf("小王大王");
    }else
    {
        printf("%d %d %d",x,y,z);
    }
    return 0 ;
}

F、路径

这个问题的核心是动态规划(DP)求解网格最短路径数,结合 "只能向右 / 向下走(最短路径的唯一走法)" 的规则,通过状态转移方程递推所有路径数,最终对结果取模。

问题本质(最短路径的约束)

网格中从起点 (0,0) 到终点 (n-1,m-1) 的最短路径,只能由 "向右(→)" 和 "向下(↓)" 两种移动组成(任何向左 / 向上的移动都会增加路径长度)。

  • 最短路径的总步数固定:需要走 (n-1) 次向下 + (m-1) 次向右 = n+m-2 步;
  • 路径数等价于:在 n+m-2 步中选择 n-1 步向下(或 m-1 步向右)的组合数,即 C(n+m−2,n−1)(组合数公式)。
cpp 复制代码
#include<stdio.h>
#include<math.h>
#define N 2000
int a[N][N];
int main() {
    int n, m, i, j;
    scanf("%d%d", &n, &m);
    for ( i = 0; i <N; i++)
    {
        a[i][0] = 1;
        a[0][i] = 1;
    }
    for ( i = 0; i <n; i++)
    {
        for ( j = 0;  j <= m;  j++)
        {
            a[i + 1][j + 1] = (a[i][j + 1] + a[i + 1][j]) % 1000000007;
        }
    }
    printf("%d", a[n-1][m-1]);
    return 0;
}
相关推荐
ohoy20 小时前
EasyPoi 数据脱敏
开发语言·python·excel
开开心心_Every1 天前
Word转PDF工具,免费生成图片型文档
网络·笔记·pdf·word·powerpoint·excel·azure
艾上编程2 天前
第一章——办公自动化之Excel拆分工具:精准处理数据,提升办公效能
自动化·excel
夜流冰2 天前
Excel - MS Support for Excel: Get started
excel
缺点内向2 天前
如何在 C# 中创建、读取和更新 Excel 文档
c#·.net·excel
YuanYWRS2 天前
办公基础:实现PDF中表单不改变格式的情况下转成excel
pdf·excel
Data_agent2 天前
Python高效实现Excel与TXT文本文件数据转换指南
开发语言·python·excel
米芝鱼3 天前
Unity读取Excel转换为二进制数据文件与自定义数据读写
游戏·unity·游戏引擎·excel·urp
用户298698530143 天前
如何在 C# 中创建、读取和更新 Excel 文档
后端·c#·excel