HDU5351 MZL's Border

今天的多校试题是高中出的,被严重吐槽。有道题竟然是化学题,这让即将步入大三的人来说,情何以堪,这道题让我们队WA了一次,不过最后还是过了。整体来说,这次出的题不是太好,简单题太简单,难题又太难,中间题的数量太少。曾经有一个多小时,绝大多数队伍都是三道题。第九题,我们队纠结于用java还是c++写(哎,当时,真是,主要是java不熟练,c++又没有“大数”,必须自己写个“大数”)。最后,纠结来纠结去,我们队还是用C++写了,写完已经快到点了,只测了样例就交了,结果,WA。比赛完后,改了改,就过了。
比赛完后,HDU把它放在了5351的题位上,题意很复杂,解题方法是找规律。找到第一个使m+1<F[i]的i值,答案就是m-F[i-2](F为斐波那契数列,注意:当m==1时,直接就是1了)
附上AC的代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define MOD 258280327
int n;
struct s
{
    int a[1050];
    void set()
    {
        memset(a,0,sizeof(a));
    }
}f[1050];
s ss;
s operator +(s const &m,s const &n)
{
    s temp;
    temp.set();
    for(int i=0;i<1050;i++)
    {
        temp.a[i]+=m.a[i]+n.a[i];
        if(temp.a[i]>9)
        {
            temp.a[i+1]++;
            temp.a[i]-=10;
        }
    }
    return temp;
}

s operator -(s const &m,s const &n)
{
    s tem;
    tem.set();
    for(int i=0;i<1050;i++)
    {
        tem.a[i]=m.a[i];
    }
    for(int i=0;i<1050;i++)
    {
        tem.a[i]-=n.a[i];
        if(tem.a[i]<0)
        {
            tem.a[i]=10+tem.a[i];
            tem.a[i+1]--;
        }
    }
    return tem;
}

bool operator >(s const &m,s const &n)
{
    int lm,ln;
    for(lm=1000;m.a[lm]==0;lm--);
    for(ln=1000;n.a[ln]==0;ln--);
    if(lm>ln)
        return true;
    else if(lm<ln)
        return false;
    for(int i=lm;i>=0;i--)
    {
        if(m.a[i]>n.a[i])
            return true;
        else if(m.a[i]<n.a[i])
            return false;
    }
    return false;
}
void init(int n)
{
    for(int i=1;i<=n;i++)
        f[i].set();
    f[1].a[0]=1;
    f[2].a[0]=1;
    for(int i=3;i<=n;i++)
        f[i]=f[i-1]+f[i-2];
}
void change(string m)
{
    ss.set();
    for(int i=0;i<m.length();i++)
    {
        ss.a[m.length()-1-i]=m[i]-'0';
    }
    s k;
    k.set();
    k.a[0]=1;
    while(f[n]>ss+k)
    {
        n--;
    }
}
long long g()
{
    long long ans=0;
    int i;
    s temp=ss-f[n-1];
    for(i=1000;temp.a[i]==0;i--);
    for(int j=i;j>=0;j--)
        ans=((ans*10)%MOD+temp.a[j]%MOD)%MOD;
    return ans;
}
int main()
{
    int t;
    string m;
    long long ans;
    init(1001);
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        cin >> m;
        if(m.length()==1&&(m[0]=='1'))
        {
            puts("1");
            continue;
        }
        int i;
        change(m);
        ans=g();
        printf("%lld\n",ans);
    }

    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值