PAT 1093.Count Pat's

本文介绍了一种优化算法,用于高效计算字符串中特定字符组合(PAT)的数量。通过两次遍历构建前缀和后缀信息,再进行一次遍历计算结果,实现了时间和空间的高效利用。文章详细解释了算法原理,并提供了完整的C++代码实现。

一开始想着的事记录p的位置a的位置t的位置,然后再去找每个p后面有多少个a,以及这个a后面有多少个t。
后来看了人家的解法,发现其实可以统计每个a前面有多少个p,以及后面有多少个t。然后把结果乘起来,然后再加起来就可以了。
两次遍历构建,一次遍历计算结果。
完美。好好学,好好看。

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <cstdio>
#include <map>
#include <math.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

const int maxn = 1000000007;
int pp[100111];
int tt[100111];
char pat[100111];

int main()
{
    int i,j,k,m,n;
    gets(pat);
    k = strlen(pat);
    m = 0;
    for(i = 0;i < k;i++)
    {
        if(pat[i] == 'P')
            m++;
        else if(pat[i]=='A')
            pp[i] = m;
    }
    n = 0;
    for(i = k-1;i > 0;i--)
    {
        if(pat[i] == 'T')
            n++;
        else if(pat[i]=='A')
            tt[i] = n;
    }
    long long ans = 0;
    for(i = 1;i<k-1;i++)
        if(pat[i] == 'A')
            ans = (ans + pp[i] * tt[i])%maxn;
    ans = ans % maxn;
    printf("%d\n", ans);

    return 0;
}
<think>我们有一个需求:查询表tab_queue_patient中,在指定时间范围内,状态status为'等待中'(即status='等待中')的数据数量。 根据用户描述,时间范围是从某个开始时间(假设为start_time)到某个结束时间(假设为end_time)。但是用户给出的时间范围描述中,开始时间和结束时间的具体值在问题中是用单引号空着的,所以我们需要用占位符表示。 因此,我们需要构建一个SQL查询,条件包括: 1. 状态:status = '等待中' 2. 时间范围:我们假设表中有一个表示时间的字段(用户未给出字段名,这里假设为wait_time,实际中可能需要根据表结构调整)。这个时间字段的值应该在给定的时间区间内(包括开始时间,不包括结束时间?包括结束时间?通常,时间范围是左闭右开,即[开始时间, 结束时间)) 但是用户没有指定时间字段的名称。根据常见的命名,可能是`create_time`、`queue_time`等。这里我们假设为`queue_time`,因为是在排队中的记录。如果实际表结构不同,请替换为正确的字段名。 我们还需要注意:用户要求的是在时间范围内的记录数量,所以使用COUNT(*)来计数。 因此,基本的SQL语句如下: SELECT COUNT(*) FROM tab_queue_patient WHERE status = '等待中' AND queue_time >= '开始时间' AND queue_time < '结束时间'; 注意:这里使用queue_time >= 开始时间 AND queue_time < 结束时间,表示时间范围是[开始时间, 结束时间),即包含开始时间,不包含结束时间。这是常见的做法,避免重复计算结束时间点。 但是用户提供的引用中并没有直接相关的SQL,不过我们可以参考引用中的一些写法: 引用[1]:展示了多表连接和子查询,但我们的需求是单表查询,不需要连接。 引用[2]:提到了使用RANK()和子查询,以及TOP语句(在SQL Server中TOP可能会影响性能,但我们的查询是COUNT,不涉及分页,所以不需要TOP)。 引用[3]:提到MyBatis中SQL执行但结果绑定问题,与我们的SQL编写无关。 因此,我们只需要简单的单表查询即可。 如果用户的时间范围是包含开始时间和结束时间,那么我们可以使用: queue_time BETWEEN '开始时间' AND '结束时间' 但是注意,BETWEEN是闭区间,如果结束时间是精确到秒,那么会包含结束时间这一时刻。如果结束时间我们想表示到某一时刻(比如2025-12-18 01:00:00),那么使用BETWEEN会包含01:00:00这一秒,而通常我们希望的时间段是00:00:00到01:00:00,不包含01:00:00,所以使用: queue_time >= '2025-12-18 00:00:00' AND queue_time < '2025-12-18 01:00:00' 所以,最终的SQL语句为: SELECT COUNT(*) AS waiting_count FROM tab_queue_patient WHERE status = '等待中' AND queue_time >= '开始时间' -- 替换为实际开始时间,格式为'YYYY-MM-DD HH:MM:SS' AND queue_time < '结束时间'; -- 替换为实际结束时间 如果用户的时间字段是日期和时间分开存储,或者存储的是时间戳,可能需要调整。但这里我们假设是标准的日期时间类型。 另外,如果用户需要动态传入开始时间和结束时间,那么在MyBatis中可以使用参数占位符,例如: SELECT COUNT(*) FROM tab_queue_patient WHERE status = '等待中' AND queue_time >= #{startTime} AND queue_time < #{endTime} 注意:在MyBatis中,参数名需要与传入的参数对象属性名一致。 如果用户的问题中时间字段不是queue_time,请根据实际表结构修改。 由于用户没有提供具体的字段名,我们只能假设。如果实际表结构不同,请替换字段名。 根据用户需求,我们修改SQL语句以实现查询指定时间范围内状态为'等待中'的数据数量。 因此,我们给出如下答案: </think> 根据您的需求,需要查询`tab_queue_patient`表中在指定时间范围内状态为`等待中`的记录数量。以下是修改后的SQL语句及详细说明: ### 修改后的SQL语句 ```sql SELECT COUNT(*) AS waiting_count FROM tab_queue_patient WHERE status = '等待中' -- 筛选状态为"等待中"的记录 AND queue_time >= '2025-12-18 00:00:00' -- 替换为实际开始时间 AND queue_time < '2025-12-18 01:00:00'; -- 替换为实际结束时间 ``` ### 关键点解析 1. **状态筛选** `status = '等待中'` 精确匹配状态字段值为`等待中`的记录。 2. **时间范围控制** - 使用 `queue_time >= [开始时间] AND queue_time < [结束时间]` 确保: - 包含起始时刻(`00:00:00`) - 不包含结束时刻(`01:00:00`),避免跨时段数据重复统计 - 时间格式必须与数据库存储格式一致(通常为 `YYYY-MM-DD HH:MM:SS`) 3. **性能优化** - 对`queue_time`和`status`字段建立复合索引可加速查询: ```sql CREATE INDEX idx_status_time ON tab_queue_patient(status, queue_time); ``` - 避免使用`BETWEEN`(可能包含边界值问题)或函数计算(如`YEAR()`),直接比较时间戳[^2] ### 动态参数示例(MyBatis) 若在MyBatis中使用参数化查询: ```xml <select id="countWaitingPatients" resultType="int"> SELECT COUNT(*) FROM tab_queue_patient WHERE status = '等待中' AND queue_time >= #{startTime} AND queue_time < #{endTime} </select> ``` 需确保传入的 `startTime` 和 `endTime` 为 `java.time.LocalDateTime` 类型[^3]。 ### 注意事项 1. **时区问题**: 若数据库存储UTC时间,需转换时区: ```sql AND CONVERT_TZ(queue_time, '+00:00', '+08:00') >= '2025-12-18 00:00:00' ``` 2. **空值处理**: 添加 `AND queue_time IS NOT NULL` 避免遗漏异常数据 3. **执行验证**: 通过MyBatis日志确认最终执行的SQL是否符合预期 --- **
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值