刷题笔记-24年3月第二组
Created at Updated at

1625 Words

24年-3月-第二组

P1307 ★

数字反转:输入一串数字,将其翻转过来

思路

感觉思路很简单:

  • 将整型数字转换成string型
  • 倒着读取string型的字符
  • 输出字符 有些问题没有考虑到:
  • 忽略了倒置后数字最前端的0没有去掉 解决方法:
  • 更改最末端指针的位置:
int last=str.size()-1;  //最初始的位置
while(str.at(last)=='0'&&last>0)   //这里的条件判定要准确
	{
		last--;
	}

总结

  • 要灵活使用string库中的函数:str.at(i) str.substr(position,length)等
  • 要注意不能越界访问

P1317 ★

低洼地:用数组来表示数轴上水平线的高低,统计出洼地的数量

思路

画图可以很直观的理解

配图

  • 排除首尾点
  • 判断该点高度与前后点的高度差的乘积是否为一负一正 我编写的判断逻辑如下:
    for(int i=1;i<n-1;i++)
    {
        if(num[i]-num[i-1]<0&&num[i]-num[i+1]<=0)
        {
            count++;
        }
    }

有一个点通过不了OJ测试,发现确实有逻辑漏洞,如果最后倒数第二个点与尾端点水平,则仍然算作洼地;

思路2

改用while 循环,用i当作游标,一个一个遍历节点,all ac,关键在于游标的游动

    while(i>=1&&i<n-1)    //改用while循环
    {
        if(num[i]-num[i-1]<0&&num[i]-num[i+1]<0) //该点左高右高,是典型的洼地
        {
            count++;
        }
        if(num[i]-num[i-1]<0&&num[i]-num[i+1]==0) //左高右平地,将标记向不断向右边移动
        {
            for(int j=i+2;j<n;j++)
            {
                if(num[j]-num[j-1]>0)
                {
                    count++;
                    i=j;
                    break;
                }
            }
        }
        i++;
    }

总结

思路不算难,细节的处理是个问题,怎么移动游标要弄清楚;

P1319 ★

压缩技术:第一个数字表示矩阵的维数,或者说字块的大小,接下来的数字表示有几个连续的0,连续的1交错;

思路1

  • 根据第一个输入的值创建矩阵\数组;

  • 填充数组

行不通,卡了好久,准备看题解;

思路2

  • 先创建一个一维数组;
  • 设定一个布尔变量,表示该向数组里填入0还是1;
  • 用for循环向数组内填充元素;
    while(cin>>input)  //第一次用到这种while循环,边输入边操作
    {
        int i=p;
        for(i;i<p+input;i++)
            num[i]=flag;
        p=p+input;
        flag=!flag;
        if(p==n*n) break;   //判定什么时候输入停止
    }

总结

思路不是很难,一些操作上卡了很久:不知道什么时候中断输入,我加了条件判定后break才能中断输入,与高赞的解法不太一样,不太清楚他那种不判定就可以结束的原理;

P1320 ★★★★★

压缩技术(续集):上一道题的反向求解,通过汉字点阵找出汉字的压缩码;

思路

  • 先要读入汉字点阵,但是不清楚点阵每行的元素数量;
  • 输出:用for循环计数统计,然后输出压缩码;
bool key=false;
    while(cin>>str)   //读入数据,按维数结束中断
    {
        l=str.size();
        count++;
        if(count==1) key=stoi(str.substr(0,1));
        for(int i=0;i<l;i++)
        {
            if(str.at(i)-'0'==key)
            {
                num[p]++;
            }
            else
            {
                p++;
                key=str.at(i)-'0';
                num[p]++;
            }
        }
        if(count==l) break;  //行数输入够了就中断循环
    }

总结

本地测试都没有问题,下载了测试点的数据,发现结果有偏差,可能是OJ的问题,有待进一步考虑

P1321 ★

单词覆盖还原:统计出单词的个数,包括已经被覆盖的;

思路

没太看懂题

题解

    for(int i=0;i<str.size()-2;i++)
    {
        if(str[i]=='b'||str[i+1]=='o'||str[i+2]=='y')
        {
            count1++;
        }
    }
    for(int i=0;i<str.size()-3;i++)
    {
if(str[i]=='g'||str[i+1]=='i'||str[i+2]=='r'||str.at(i+3)=='l')
        {
            count2++;
        }
    }

总结

判断逻辑很简单,但是一开始没有弄对for循环的边界是size-2和size-3;

P1401 ★

禁止int int 时不开long long: 判断输入的两个范围是否会超过int型的表示范围;

思路

  • 读取数据,找出每行中绝对值中最大的;
  • 判断是否会超出范围 该思路行不通,不能只考虑绝对值,因为上溢出和下溢出的界限不一样,是错解.

思路

  • 分别用longlong型和int型存放乘积
  • 比较不同类型的乘积是否相等

总结

  • 取绝对值的方法
#include<cmath>
fabs(number);
  • 可以通过比较两种不同类型的存储方式下的值是否相等来判断是否溢出;

P1420 ★

最长连号:输入最长的连续自然数的长度;

思路

  • 输入数组
  • 判断连号的长度

总结

挺水的一道题

    while(p<n)    //p用作指针用于移动
    {
        if(num[p]+1==num[p+1])
        {
            p++;
            count++;
        }
        else
        {
            if(count>=max) max=count;   //连号断了,初始化
            count=1;  //重置count的数值
            p++;
        }
    }

P1421 ★

小玉买文具: 班主任给小玉a元b角,签字笔的价格是1元9角,求小玉最多能卖多少支笔;

思路

  • 先输入a和b;
  • 算小玉能卖多少支笔

总结

int main() { int a=0,b=0; //输入a元b角 cin»a»b; float sum=a+b*0.1; float num=floor(sum/1.9); cout«num; return 0; }

很简单的一道题,注意向下取整需要调用cmath库

P1422 ★

小玉家的电费:计算小玉家的电费,梯度收费;

思路

大概知道应该用条件判断梯度收费

  • 用float存放花销cost
  • 最后输出cost时保留一位小数
  • 保留一位小数的方法
#include<cmath>
double number = 3.1415926
number = round(number*10)/10;

总结

刷到目前遇到的最容易的一题;

P1423 ★

小玉在游泳:又是一道计算题,第一次游泳2m,下一步是上一次游的距离的0.98;计算游到s米需要花多少时间;

思路

  • 读入需要游泳的距离s;
  • 计算步数;
  • 输出步数;

总结

很简单的一道题,注意精度不够高可能通过不了OJ的测试;