2018ECNA Difference[时空复杂度]

题干

1559979-20190819213759190-178097841.png
1559979-20190819213806627-154528435.png

代码和解释

本题给出一个数列的第一个数A(1),要求找出m第一次出现(直接出现在数列中或是数列中某两项的差的绝对值)在这个数列的第几步中。数列递推公式:A(n+1)=A(n)+min,min是最大的从1开始未出现在数列中且未出现在数列中某两项的差值的绝对值中的整数。
第一遍做此题时,我定义了一个结构体node存储每一步时数列的值以及这项与之前所有项的差值,并定义了这个结构体类型的vector来存储所有项及差值,同时定义了一个整型数组bul存储每一个数是否出现过的信息;
1559979-20190819212831140-813734326.png
第二遍删去了结构体,用一个整数存数列中某项的值,并定义了一个整型的vector存储所有项,定义了一个数组diffs存储数列中某项与之前所有项值的差值,同时定义了一个整型数组bul存储每一个数是否出现过的信息;
1559979-20190819212840284-1592156265.png
这两次都以Runtime Error失败,在老师的指导下,我知道了自己第二遍的代码中bul和diffs两个数组占内存大小已达1.6个g之多(int型4个字节,(410^8)4个字节),严重超出内存要求,老师建议我使用char型数组代替bul,同样可以达到要求,且char型只占1个字节。而我也发现,diffs这个用于存储差值的数组并没有存在的必要,删去之。第三遍代码上交后报错为time limit exceeded,这时我想到最近刚学了list添加和删除元素要比vector快,于是将v改成list型,成功ac了。
1559979-20190819213425781-838101421.png
下面是最终的c++代码

#include<iostream>
#include<list>
#include<string.h>
using namespace std;
char bul[200000005];//因为数组太大,放到全局变量可以解决这个问题。使用char型可以解决int型超出内存的问题! 
int main()
{
    int tv;//temporary value
    list<int> v;
    int A1;
    long long m;
    int i,j,f;
    int min;
    int tmp;
    int lastk;
    list<int>::iterator it;
    list<int>::iterator it2;
    while(~scanf("%d%lld",&A1,&m)){ 
        v.clear();//初始化 
        tv=A1;
        v.push_back(tv);
        if(m==A1){
            printf("%d\n",1);
            break;
        }
        min=A1;
        memset(bul,'0',sizeof(bul));//初始化 
        bul[A1]='1';//第一个值有了 
        f=0;
        long long k = 1;//k存新的未出现的数 
        while(f==0){
            //先是添加,只要跟v的上一位比较即可 
            lastk=k;
            //寻找min的值 
            while(1){
                if(bul[k]=='0'){
                    min=k;
                    k++;
                    break;
                }
                k++;                
            }   
            it=v.end();
            it--;//表示比v.size()少一位的大小 
            tv=*it+min;
            bul[tv]='1';//这个值有了 
            bul[min]='1';// 
                    
            for(it2=v.begin();it2!=it;it2++){//这里不能用小于号,只能用不等号 
                bul[tv-*it2]='1';//新出现的差值 
            }
            v.push_back(tv);            
            
            //再是查找是否有m,只要找v最新的一位即可
            if(bul[m]=='1'){
                printf("%d\n",v.size());
                break;
            }
        }
    }
    return 0; 
} 

解决本题使我认识到了做题时要注意考虑内存和时间,以及一些其他小教训,比如定义大的数组应该定义为全局变量,在结构体中定义数组要指明数组大小等。

转载于:https://www.cnblogs.com/hardcoreYutian/p/11379633.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值