电子科技大学链时代工作室招新题C语言部分---题号G

1. 题目

 

问题的第一段也是非常逆天,说实话,你编不出问题背景可以不编。

这道题的大概意思就是, Pia要去坐飞机,那么行李就有限重。这时Pia想到自己带了个硬盘,众所周知,硬盘上存储的数据就是0和1的二进制序列。

对于一段二进制序列,每有一个从0到1的过渡,或是从1到0的过渡(也就是每有一个0和1的分界),就会导致硬盘的重量轻微增加一点,为了不超重,Pia就需要修改一下硬盘上存储的数据。

然而硬盘上的某些位置是坏掉的,坏掉的位置只能存入0,其中,第一个位置永远是好的,最后一个位置永远是坏的。

输入

第一行,分别输入三个数n,c,b(2<=n<=5.10^{5},1<=c,b<=n-1)。

n表示二进制序列的长度,c表示所需分界位置的数量,b表示损坏位置的个数。

第二行输入损坏位置的位置信息。

输出

输出符合条件的二进制序列。


2. 第一版解法

2.1 思路

1. 首先我们肯定需要依据n开辟一个数组,但接下来我们就有两种选择,将数组元素全部初始化为0或全部初始化为1。

2. 如果我们将数组全部初始化为0,那么我们在将某个元素改为1时,需要先检查其是否为损坏的位置,每次都需要遍历储存位置信息的数组。

3. 如果我们将数组初全部始化为1,那么我们只需要在初始化结束之后把损坏的位置改为0即可,并在之后的过程中,确保只将1改为0,而不将0改为1。

4. 第一个位置始终是好的,最后一个位置始终是坏的。这个条件对边界上的位置进行了限制,边界上的位置有什么特殊的吗?

我们发现,边界上出现1,最多只会导致1次变化,而中间位置上出现1(不与边界1相连),一定会导致2次变化。

所以,如果题上要求的变化次数为奇数,那么一号位一定是1;如果题上要求的变化次数为偶数,则一号位上一定不是1。

add原本指向数组开头,这里将与一号位相连的1都抛开不看了(有问题,下一版会该)

if(c%2 == 0)
{
    bit[0] = '0';
}
else
{
    bit[0] = '1';
    c--;//所需减一
    while(*(++add) == '1');
}

5. 在将一号位调整好之后就可以先将其抛开不看了,将add当作数组开头进行进一步调整。

6. 接下来我们的做法是记录每一段1的起始与结束位置,如果当前发生字节改变的位置比要求的少,那么就将某一段1分割为两段,中间用0隔开;如果当前发生字节改变的位置比要求的多,那么就将某一段1全部置为0。

2.2 代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct posi
{
    char* start;
    char* end;
}posi;

int main()
{
    int n = 0, c = 0, b = 0, count = 0;//硬盘大小,所需字节改变处数量,受损坏字节数量,1的段数
    char sep[] = {'0'};
    scanf("%d %d %d", &n, &c, &b);
    char* bit = (char*)malloc(sizeof(char) * (n + 1));//存结果
    bit[n] = '\0';
    bit[n-1] = '0';
    char* add = bit;
    for(int i = 0; i < n - 1; i++)
    {
        bit[i] = '1';
    }
    int* Bre = (int*)malloc(sizeof(int) * b);//损坏字节的位置
    for(int i = 0; i < b; i++)
    {
        scanf("%d", &Bre[i]);
        bit[Bre[i]-1] = '0';
    }
    if(c%2 == 0)
    {
        bit[0] = '0';
    }
    else
    {
        bit[0] = '1';
        c--;//所需减一
        while(*(++add) == '1');
    }
    posi* ret = (posi*)malloc(sizeof(posi) * n / 2);
    for(ret[count].start = strtok(add, sep); ret[count].start != NULL; ret[++count].start = strtok(NULL, sep))//记录每段1的起始和结束位置
    {
        char* tmp = ret[count].start;
        while(*tmp != '\0'){tmp++;}
        ret[count].end = tmp - 1;
    }
    int i = 0;
    if(count == 0)
    {
        if(add >= bite + 3&&2 * count != c)//1111110
        {
            bit[1] = '0';
            ret[count].start = bite + 2;
            ret[count].end = add - 1;
            count++;
        }
        else//10000000
        {
            printf("%s\n", bit);
    
            free(bit);free(Bre);free(ret);
    
            return 0;
        }
    }
    while(2 * count < c&&i < n / 2)//改变的少了
    {
        if(ret[i].end - ret[i].start >= 2)
        {
            *(ret[i].start + 1) = '0';
            ret[count].start = ret[i].start + 2;
            ret[count].end = ret[i].end;
            count++;
            ret[i].end = ret[i].start + 1;
        }
        else
        {
            i++;
        }
    }
    
    while(2 * count > c&&i < n / 2)//改变的多了
    {
        while(ret[i].start <= ret[i].end)
        {
            *(ret[i].start++) = '0';
            *(ret[i].end--) = '0';
        }
        i++;
        count--;
    }

    for(int j = 0; j < n; j++)
    {
        if(bit[j] == '\0')
        bit[j] = '0';
    }
    printf("%s\n", bite);
    
    free(bit);free(Bre);free(ret);
    
    return 0;
}

2.3 总结

这一段代码的问题就在于add那里,将开头连续的1一并忽视掉。

这就会导致需要单独处理一开始就只有开头连续1的情况,我们已经说过,当你开始考虑特殊情况时,你就已经输了一半。

不止如此,这还会导致我们能产生的最多字节变化的数量减少,因为开头的连续1也可以断开产生更多变化字节。


3. 最终版解法

3.1 思路

这一版就将add给删除了,当b为奇数时,将一号位置为1,然后直接将二号位置为0。

这样做就可以达到目的了,而且无需考虑特殊情况,可以说add这个变量简直是画蛇添足。

3.2 代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct posi
{
    char* start;
    char* end;
}posi;

int main()
{
    int n = 0, c = 0, b = 0, count = 0;//硬盘大小,所需字节改变处数量,受损坏字节数量,1的段数
    char sep[] = {'0'};
    scanf("%d %d %d", &n, &c, &b);
    char* bit = (char*)malloc(sizeof(char) * (n + 1));//存结果
    bit[n] = '\0';
    bit[n-1] = '0';
    for(int i = 0; i < n - 1; i++)
    {
        bit[i] = '1';
    }
    int* Bre = (int*)malloc(sizeof(int) * b);//损坏字节的位置
    for(int i = 0; i < b; i++)
    {
        scanf("%d", &Bre[i]);
        bit[Bre[i]-1] = '0';
    }
    if(c%2 == 0)
    {
        bit[0] = '0';
    }
    else
    {
        bit[0] = '1';
        bit[1] = '0';
        c--;//所需减一
    }
    posi* ret = (posi*)malloc(sizeof(posi) * n / 2);
    for(ret[count].start = strtok(bite + 1, sep); ret[count].start != NULL; ret[++count].start = strtok(NULL, sep))//记录每段1的起始和结束位置
    {
        char* tmp = ret[count].start;
        while(*tmp != '\0'){tmp++;}
        ret[count].end = tmp - 1;
    }
    int i = 0;
    
    while(2 * count < c&&i < n / 2)//改变的少了
    {
        if(ret[i].end - ret[i].start >= 2)
        {
            *(ret[i].start + 1) = '0';
            ret[count].start = ret[i].start + 2;
            ret[count].end = ret[i].end;
            count++;
            ret[i].end = ret[i].start + 1;
        }
        else
        {
            i++;
        }
    }
    
    while(2 * count > c&&i < n / 2)//改变的多了
    {
        while(ret[i].start <= ret[i].end)
        {
            *(ret[i].start++) = '0';
            *(ret[i].end--) = '0';
        }
        i++;
        count--;
    }

    for(int j = 0; j < n; j++)
    {
        if(bit[j] == '\0')
        bit[j] = '0';
    }
    printf("%s\n", bit);
    
    free(bit);free(Bre);free(ret);
    
    return 0;
}

3.3 总结

还是那句话,当你的代码需要考虑特殊输入情况时,你就要想办法改改它了,尽管它看起来万无一失。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/469584.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

elasticsearch安装部署

elasticsearch部署 安装elasticsearch1.部署单点es1.1.创建网络1.2.加载镜像1.3.运行 2.部署kibana2.1.部署2.2.DevTools 3.安装IK分词器3.1.在线安装ik插件&#xff08;较慢&#xff09;3.2.离线安装ik插件&#xff08;推荐&#xff09;3.3 扩展词词典3.4 停用词词典 4.部署es…

列表的常用操作

列表的常用操作&#xff08;方法&#xff09; 列表除了可以&#xff1a; 定义使用下标索引获取值 此外列表也提供一些列功能&#xff1a;插入元素删除元素清空元素修改元素统计元素个数 等等功能&#xff0c;这些功能我们都称之为&#xff1a;列表的方法 列表的查询功能&…

七:分布式

一、Nginx nginx安装 【1】安装pcre依赖 1.下载压缩包&#xff1a;wget http://downloads.sourceforge.net/project/pcre/pcre/8.37/pcre-8.37.tar.gz 2.解压压缩包&#xff1a;tar -xvf pcre-8.37.tar.gz 3.安装gcc&#xff1a;yum install gcc 4.安装gcc&#xff1a;yum ins…

Java的图书管理系统,确实有两把斧子 ! ! !

本篇会加入个人的所谓‘鱼式疯言’ ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

HCIE考证心得 | 在云校的学习收获颇多

我是来自深圳信息职业技术学院22级现代移动通信3-3班的冯同学&#xff0c;我在2023年12月12日通过了华为认证Cloud Service HCIE。在此&#xff0c;我将分享考证中的心得体会给大家。 备考的六点建议 一是要细心严谨&#xff0c;做实验时要全神贯注&#xff0c;明确实验要求…

基于python考试分析系统的设计和实现-flask-django-nodejs-php

随着电子技术的普及和快速发展&#xff0c;线上管理系统被广泛的使用&#xff0c;有很多商业机构都在实现电子信息化管理&#xff0c;图书推荐也不例外&#xff0c;由比较传统的人工管理转向了电子化、信息化、系统化的管理。   本文的重点是对考试分析系统展开了详细的描述&a…

填坑记5:安装imdb库失败 ERROR: No matching distribution found for imdb

收录于《填坑记》 一、问题 pip install imdb在网上查找原因&#xff0c;有以下几种可能&#xff1a; 库名拼写错误&#xff1a;首先确认你要安装的库名是否正确拼写。如果是想使用IMDb的数据&#xff0c;你可能在寻找的是 IMDbPY 这个库&#xff0c;而不是 imdb。库不存在&a…

软件开发项目管理/研发项目管理软件:国产EDA工具厂商行芯科技上线奥博思PowerProject项目管理软件平台

国内领先的EDA工具链提供商杭州行芯科技有限公司&#xff08;以下简称&#xff1a;行芯科技&#xff09;与北京奥博思软件技术有限公司达成战略合作&#xff0c;奥博思软件将基于PowerProject项目管理系统助力行芯科技实现研发项目的全生命周期管理&#xff0c;提升管理效能&am…

B010-springcloud alibaba 分布式事务 Seata

目录 分布式事务基础事务本地事务分布式事务分布式事务的场景 分布式事务解决方案全局事务/两阶段提交可靠消息服务最大努力通知TCC事务 Seata介绍Seata实现分布式事务控制案例基本代码修改order微服务OrderSeataControllerOrderServiceImpl5注释容错相关代码ProductClient 修改…

Avalon总线学习

Avalon总线学习 avalon总线可以分为&#xff1a; Avalon clock interface Avalon reset interface Avalon Memory mapped interface Avalon iterrupt interface Avalon streaming interface Avalon tri-state conduit interface Avalon conduit interface 1、Avalon c…

管道(acwing,蓝桥杯,二分)

题目描述&#xff1a; 有一根长度为 len 的横向的管道&#xff0c;该管道按照单位长度分为 len 段&#xff0c;每一段的中央有一个可开关的阀门和一个检测水流的传感器。 一开始管道是空的&#xff0c;位于 Li的阀门会在 Si 时刻打开&#xff0c;并不断让水流入管道。 对于位…

openEuler 22.03(华为欧拉)一键安装 Oracle 11G(231017)单机版

Oracle 一键安装脚本&#xff0c;演示 openEuler 22.03 一键安装 Oracle 11GR2 单机版过程&#xff08;全程无需人工干预&#xff09;&#xff1a;&#xff08;脚本包括 ORALCE PSU/OJVM 等补丁自动安装&#xff09; ⭐️ 脚本下载地址&#xff1a;Shell脚本安装Oracle数据库 …

高端嵌入式底层技术揭秘:《ARM汇编与逆向工程》

ARM架构简介 与传统的CISC&#xff08;Complex Instruction Set Computer&#xff0c;复杂指令集计算机&#xff09;架构相比&#xff0c;Arm架构的指令集更加简洁明了&#xff0c;指令执行效率更高&#xff0c;能够在更低的功耗下完成同样的计算任务&#xff0c;因此在低功耗…

2024流星全自动网页生成系统重构版源码

2024流星全自动网页生成系统重构版源码 源码介绍 流星全自动网页生成系统重构版源码分享&#xff0c;所有模板经过精心审核与修改&#xff0c;完美兼容小屏手机大屏手机&#xff0c;以及各种平板端、电脑端和360浏览器、谷歌浏览器、火狐浏览器等等各大浏览器显示。 为用户使…

FREERTOS信号量详解

信号量是操作系统中重要的一部分&#xff0c;信号量一般用来进行资源管理和任务同步&#xff0c;资源管理其实就是用变量来标记现有资源的数量&#xff0c;任务同步其实就是用标志位来控制任务的先后执行顺序&#xff0c;这些概念在操作系统中以及裸机开发中都有所涉及。 FreeR…

RK3588_Qt交叉编译环境搭建

buildroot编译 进入 /home/linux/plat/rk3588/sdk/buildroot 目录下&#xff0c;执行 Source ./envsetup.sh 选择具体平台编译&#xff0c;后再执行make编译 /home/linux/plat/rk3588/sdk/buildroot/output/OK3568/images 生成的rootfs.ext2镜像重新烧写到rk3568开发板中&…

React Native:跨平台移动应用开发的利器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

外包2月,技术退步惊现!大专生逆袭大厂,全靠这份神秘资料!

大家好&#xff0c;我是一名大专生&#xff0c;19年通过校招进入湖南某软件公司&#xff0c;从事功能测试工作已近4年。今年8月&#xff0c;我意识到长期舒适的环境让我变得不思进取&#xff0c;技术停滞不前&#xff0c;甚至因此失去了谈了2年的女朋友。我下定决心&#xff0c…

下拉树级带搜索功能

可以直接复制粘贴到自己的项目里,方法处把接口替换一下 <template><div><el-popoverplacement"bottom"width"200"trigger"click"><el-inputslot"reference"class"mrInput":placeholder"placehol…