hihocoder挑战赛20小记

本文分享了作者参加Hihoroound比赛的经历及解题思路。重点介绍了三道题(A、B、C)的解法,包括线段树、括号匹配DP以及数位DP等算法,并附上了相应的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2016.11.4
晚上六点点开了一场看上去通过人数比较多的hihoround(20),virtual participate了一下。感觉这场还是比较友好的,和我以前做的hihoround只能做一题,或者爆零不一样。在两个小时里写了3个题(A,B,C),D看上去像是个经典问题,但从来没写过(几何基本等于残疾),便直接放弃了。

这场是岛娘出的,我还以为是ta朋友出的。
感觉题挺不错。题解写的也不错。
官方题解:http://hihocoder.com/discuss/question/3329

我讲讲我的做法吧。
A:入门的区间最大值了,可能是岛娘觉得像CF一样出个很水的没代码量的A没意思,就让大家写个线段树或者ST了。
我的代码:

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>

using namespace std;

const int maxn = 1e5 + 5;

#define lson o * 2,l,mid
#define rson o * 2 + 1,mid + 1,r

struct segmentTree{
    int maxv[maxn << 2];

    void pushup(int o){
        maxv[o] = max(maxv[o << 1],maxv[o << 1 | 1]);
    }
    void build(int o,int l,int r){
        if(l == r) {maxv[o] = 0;return;}
        int mid = (l + r) >> 1;
        build(lson);
        build(rson);
        pushup(o);
    }

    void update(int o,int l,int r,int p,int val){
        if(l == r) {maxv[o] = max(maxv[o],val);return;}
        int mid = (l + r) >> 1;
        if(p <= mid) update(lson,p,val);
        else update(rson,p,val);
        pushup(o);
    }

    int query(int o,int l,int r,int ql,int qr){
        if(ql <= l && r <= qr){
            return maxv[o];
        }
        int ans = 0;
        int mid = (l + r) >> 1;
        if(ql <= mid){
            ans = max(ans,query(lson,ql,qr));
        }
        if(qr > mid){
            ans = max(ans,query(rson,ql,qr));
        }
        return ans;
    }
}tree;

int n,m;

int main(){
    cin >> n >> m;
    tree.build(1,1,maxn - 5);
    for(int i = 1;i <= n;i++){
        int t,v;
        scanf("%d%d",&t,&v);
        tree.update(1,1,maxn - 5,t,v);
    }
    int ans;
    for(int i = 1;i <= m;i++){
        int a,b;scanf("%d%d",&a,&b);
        ans = tree.query(1,1,maxn - 5,a,b);
        if(ans == 0) printf("None\n");
        else printf("%d\n",ans);
    }
    return 0;
}

B:
这是一个括号匹配类型的问题。仔细分析发现,其实可以是个dp。
dp[i]=dp[left]+1,left使s[left+1]s[i]i,ansdp[i],O(n2)dpleft,depth,pre(depth((()())),,,.线)

代码:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <stack>

using namespace std;

const int maxn = 1e6 + 5;

int dp[maxn];
int num[maxn];
char s[maxn];
char Stack[maxn];
int top;
int main(){
    scanf("%s",s + 1);
    int n = strlen(s + 1);
    top = 0;
    memset(num,0,sizeof(num));
    memset(dp,0,sizeof(dp));
    for(int i = 1;i <= n;i++){
        if(s[i] == '('){//左括号压栈
            dp[i] = 0;
            Stack[++top] = '(';
        }else{
            if(Stack[top] == ')' || top == 0){
                dp[i] = 0;
                Stack[++top] = ')';
            }else{//关键,匹配了,则层数减少,便把这一层的答案置0
                num[top] = 0;
                top--;
                dp[i] = num[top] + 1;
                num[top] = dp[i];//更新这一层答案
            }
        }
    }
    long long ans = 0;
    for(int i = 1;i <= n;i++) ans += dp[i];//cout << dp[i] << " ";
    cout << ans << endl;

    return 0;
}

C:
数位dp。
题解说二分+dp。
其实二分的过程可以包含在dp的过程中了。不错的练手题,推荐数位dp欠缺(比如我)的人写,虽然这个dp代码量不大。

我的代码(严格也不算数位dp了):

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

long long power[20];
long long pow8[20];
long long k;

int d[20];

int main(){
    power[0] = 1;
    pow8[0] = 1;
    for(int i = 1;i < 20;i++) power[i] = power[i - 1] * 10LL;
    //cout << pow10[18] << endl;
    for(int i = 1;i < 20;i++) pow8[i] = pow8[i - 1] * 8LL;
    //cout << 9LL * (pow10[18] - pow8[18]) << endl;
    cin >> k;
    bool flag = false;
    bool first = false;
    for(int p = 19;p >= 1;p--){
        long long sum = 0;
        //cout << k << endl;
        for(int j = 0;j <= 9;j++){
            if(flag){
                if(sum + power[p - 1] - ((!first && j == 0) ? 1 : 0 )>= k){
                    d[p] = j;
                    if(j != 0) first = true;
                    k -= sum;
                    break;
                }else{
                    sum = sum + power[p - 1] - (!first && j == 0);
                }
            }else{
                if(j == 4 || j == 7){
                    if(sum + power[p - 1] >= k){
                        d[p] = j;
                        if(j != 0) first = true;
                        k -= sum;
                        flag = true;
                        break;
                    }else{
                        sum = sum + power[p - 1];
                        //if(p == 2) cout << sum << endl;
                    }
                }else{
                    if(sum + power[p - 1] - pow8[p - 1]  >= k){
                        d[p] = j;
                        if(j != 0) first = true;
                        k -= sum;
                        break;
                    }else{
                        sum = sum + power[p - 1] - pow8[p - 1];
                        //if(p == 2) cout << sum << endl;
                    }
                }
            }
        }
    }
    first = false;
    for(int i = 19;i >= 1;i--){
        if(!d[i] && !first) continue;
        else{
            if(d[i] > 0) first = true;
            printf("%d",d[i]);
        }
    }   

    return 0;
}
编写目的:测试报告的核心目标是总结测试周期的活动与结果,判断系统是否符合需求。它为用户提供全面视角,展示测试发现的问题、解决方式及系统现状。 项目背景:简要介绍项目,包括发起原因、目标客户和技术栈等,帮助读者理解测试背景。 列出测试过程中使用的关键文档,如需求规格说明书、设计文档和测试计划等,确保各方能获取一致的参考信息。 定义文档中的专业术语和缩写,避免误解,确保所有人员准确理解报告内容。 概述测试的整体框架,包括目的、范围和方法论,同时提及基本假设,如需求文档的准确性和资源可用性。 设计原则:测试用例需与需求项直接关联,且随需求变化动态调整。 设计方法:采用等价类划分、边界值分析和因果图等方法,设计覆盖关键场景的测试用例。 详细描述测试环境的硬件、软件和网络配置,以便复现测试结果。 介绍测试过程中使用的方法和技术,以及相关工具,如自动化测试工具和性能测试工具。 功能测试:验证系统功能模块是否按预期工作,包括冒烟测试等快速检查。 性能测试:评估系统在不同负载下的表现,关注响应时间和吞吐量等指标。 可靠性测试:模拟实际使用场景,评估系统稳定性。 安全性测试:检查系统是否存在安全漏洞,确保数据安全。 兼容性测试:验证系统在不同环境(如操作系统、浏览器)下的运行情况。 易用性测试:评估用户体验,确保界面直观易用。 覆盖分析:分析测试覆盖程度,识别未覆盖区域。 缺陷汇总:记录测试中发现的所有缺陷,包括严重性和优先级信息。 缺陷分析:对缺陷进行分类和趋势分析,找出根本原因。 残留缺陷与未解决问题:列出未解决的问题及其对系统的影响。 测试结论:基于测试结果,判断系统是否符合发布条件。 建议:提出改进建议,帮助团队避免未来类似问题。 这份测试报告模板结构清晰,内容全面,细节丰富,非常适合指导软件测试项目的实施。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值