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