PATDay5---记录

A1046 Shortest Distance

在这里插入图片描述

读题说明

题目理解本身不困难,英文也容易看懂,一般的解法容易想到,与距离无关,其实就是一个累加问题,因为路径是规划定的,只有左右结点相邻之间有一个距离,所以无需存储结点,只需要按顺序存储距离就可,然后根据顺/逆时针算出两种距离,(sum-顺=逆)

#include<cstdio>
using namespace std;
int main()
{
    int N;
    int sum=0;
    int d[100005];
    int re[10002];
    //dis[100005];
    int m;
    scanf("%d ",&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d ",&d[i]);
        sum+=d[i];
        //dis[i]=sum;
    }
    scanf("%d",&N);
    for(int j=0;j<N;j++)
    {
        int pi,pj;
        int dp=0,dn=0;
        scanf("%d %d",&pi,&pj);
        if(pi>pj)
        {int temp;
         temp=pi;
         pi=pj;
         pj=temp;
        }
        for(int i=pi;i<=pj;i++)
        {
        dp+=d[i];
        }
        //这个for循环去掉
        //dp=dis[pj-1]-dis[pi-1];
        dn=sum-dp;
        re[j]=dn>=dp?dp:dn;
    }
    for(int i=0;i<N;i++)
    {
        printf("%d",re[i]);
        if(i!=N-1)
            printf("\n");
    }
}

结果是部分AC,仔细一看是时间复杂度问题。
极端情况下,中间的两次for循环最大复杂度达到9次方,200ms不行,所以这两个for必须去掉一个。

时间复杂度解决办法

放弃最开始的顺逆时针每次输入一个点计算法,其实有一些值是可以复用的,使用一个数组保存从第一个结点到当前结点的距离之和,之后使用两个差值替换。代码如上。

感悟

题目虽然易懂,但是要注意时间复杂度的限制。

B1010 一元多项式求导

在这里插入图片描述

读题说明

这道题目本身不难,但是需要注意一些点。

  • 如何停止输入(设置输入停止条件)
  • 当求导为0的零多项式需要输出0 0

AC代码

#include<cstdio>
using namespace std;
int main()
{
    int num[10];//根据测试,这道题目的数组最大值为10
    int m=0;
    for(int i=1;scanf("%d %d",&num[i],&num[i+1])!=EOF;i+=2)//使用scanf的返回值!=EOF作为读入结束标记
    {
        m=i+1;
    }
    for(int i=1;i<=m;i+=2)
    {
        if(!num[i+1]) 
        {
            m-=2;
            break;
        }
        num[i]*=num[i+1];
        num[i+1]-=1;
    }
    if(!num[2]||!num[1]) printf("0 0");//这一步就是零多项式
    else{
    for(int i=1;i<=m;i++)
    {
        printf("%d",num[i]);
        if(i!=m) printf(" ");
    }
    }
}

A1065 A+B and C (64bit)

在这里插入图片描述

第一次写的代码,部分AC

#include<cstdio>
using namespace std;
typedef long long LL;
int main()
{
    int T;
    scanf("%d",&T);
    for(int i=1;i<=T;i++)
    {
        bool p=false;
        LL A,B,C;
        scanf("%lld %lld %lld",&A,&B,&C);
        LL temp=A+B;
        if(A>0&&B>0&&temp<0||temp>C) p=true;
        /*if(A>0 && B>0 && temp<0) p=true;
        else if(A<0 && B<0 && temp>=0) p=false;
        else if(temp>C) p=true;
        else p=false;*/
        //  /**/内为修改后AC代码
        if(p) printf("Case #%d: true",i);
        else printf("Case #%d: false",i);
        if(i!=T) printf("\n");
    }
}

部分AC原因探求

不妨假设此时A+B已经溢出,并且是正溢出,那if的前一个判断条件为true可以成立,但是如果此时是负溢出,第一个条件不成立,接着判断temp>C,未必成立(temp取值是[0,2^63)),假如成立,那么p=true,显然不对,因为此时负溢出,意味着A+B<C。

所以判断的基本原则,应该是先排除溢出的情况,然后再讨论正常情况,在未判断完溢出情况前不可判断正常情况

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值