NHOI2017初中组解题报告

本文详细介绍了四道信息技术竞赛中的题目,包括元音字母计数、直角坐标系模拟、折纸问题和两个数的变换。解题思路涵盖字符串处理、坐标系绘制、递归算法和数学推理,强调了细节处理和分类讨论的重要性。
摘要由CSDN通过智能技术生成

 

第一题 元音字母(vowel)

【题意分析】

给定一个长度小于等于106且只包含字母的字符串,求元音字母(a,e,i,o,u)的个数。

【解题思路】

对于每一位字符逐一进行判断并统计,但要注意大小写字母的区别。可以统一转换为大写或小写方便判断。

【时空复杂度】

时间复杂度:O(n)

空间复杂度:O(n)

【解题反思】

此题作为比赛的第一题,难度较低,但仍要注意一些细节:

1.          若C++选手使用字符数组,考虑到数据范围较大,必须设为全局变量,否则可能引发运行时错误。

2.       C++中的string是从第0位开始储存的,如果从1开始计算可能导致答案错误。

3.       题目中已经明文提示了,要注意大小写的区别。

【参考程序】

#include <algorithm>

#include <cctype>

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <iostream>

 

using namespace std;

 

const int maxlen = 1e6 + 100;

 

char str[maxlen];

 

int main(void) {

    freopen("vowel.in","r", stdin);

    freopen("vowel.out","w", stdout);

    gets(str);

    int ans =0;

    for (int i= 0; str[i] != '\0'; i++) { //char数组的最后一位为'\0'

        char ch= tolower(str[i]); //统一将当前位转为小写

        ans +=ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u';

    }

    printf("%d\n",ans);

    return 0;

}

第二题 直角坐标系(coordinates)

【题意分析】

给定平面直角坐标系中的n个格点(所有的点两两不同),按一定的原则绘制该坐标系:

1.          整个坐标系分为四个象限,只要该象限或与其相邻的两个象限中同时存在格点,就必须将该象限绘制出来。

2.      格点所在的坐标表示为‘*’

3.      在与原则2不冲突的情况下,x 轴表示为‘|’,y轴表示为‘-’,原点表示为‘+’

【解题思路】

直接按照题意模拟即可,但具体的实现上要注意细节。平面直角坐标系中点坐标的表示法为(x,y),但输出时是由上至下(y递减)、由左至右(x递增)的,故要进行处理。

首先要确定输出的范围,通过观察样例可以发现,如果记最终输出的坐标系当中x的取值范围为[minx,maxx],那么就有minx=min{ xi­,0},maxx=max{ xi,0},y同理。

之后则以y递减,x递增的顺序打印整个坐标系,判断当前位置是否存在点有两种方法:

一、数组计数法(我在考试时的写法)

考虑到数据范围较小,且不存在重复的点,不妨在输入时用bool数组a[j][i]表示横坐标为j、纵坐标为i的位置是否存在点。但C++中数组下标从0开始,又因为坐标的绝对值不超过100,因此可以统一加上100即可避免出现负数的问题。此方法的编程复杂度较低。

30%的做法:不考虑点坐标的正负性,直接进行标记。

二、   点排序法

可以将输入的点用struct保存(也可用STL中的pair实现)并按输出顺序的优先级排序,在输出时用k表示下一个格点在struct数组中的下标,若p[k].x==jp[k].y==i则当前位置是格点,输出‘*’后将k累加,指向下一个点。此方法的空间复杂度较低。

需要注意的是,由于枚举每一个位置并判断输出的这一过程是不可能省去的,故时间复杂度不可能比方法一更优。但此方法不必担心坐标的正负性问题,风险较低。

【时空复杂度】

不妨记坐标值的跨度范围为m,点的个数为n(显然0≤nm2),有:

数组计数法:

时间复杂度:O(m2)

空间复杂度:O(m2)

点排序法:

时间复杂度:O(m2)

空间复杂度:O(n)

【解题反思】

1. 我在考试时编写的程序没有AC,是因为忽略了在原点位置有一个点的情况。由此可见,对于此类难度不高的模拟题,一定要小心谨慎,“细节决定成败”。

2. 在考试这种限时的场合,在考虑到多种不同的实现方法时,应粗略计算各自的时空复杂度、编程复杂度和期望得分,加以比较后再决定策略,编写程序。

【参考程序】

方法一:

#include<algorithm>

#include<cctype>

#include<cstdio>

#include<cstdlib>

#include<cstring>

#include<iostream>

 

usingnamespace std;

 

constint maxp = 1e3; //坐标值的最大跨度,稍微开大一些,空间上不会有问题

 

intn;

boolf[maxp][maxp]; //第一维为横坐标(列),第二维为纵坐标(行)!!

 

intmain(void) {

    freopen("coordinates.in","r", stdin);

    freopen("coordinates.out","w", stdout);

    scanf("%d", &n);

    memset(f, false, sizeof f);

    int minx = 0, miny = 0, maxx = 0, maxy = 0;//必须包含坐标轴,故初始化为0

    for (int i = 0; i < n; i++) {

        intx, y;

        scanf("%d%d", &x, &y);

        minx =

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值