Happy Birthday!!!
T1:
样例输入:
1 6 7 3
样例输出:
2
题解:
显然前两行都与前面的数有关,就猜测第三行也与前面的数有关,于是得到第四行。很明显可以发现第四行aa的系数比第三行多11,bb的系数比第三行少11。
所以不用管前两行,把第三行直接列出来就行了。方程:
sum1[i]=sum1[i-1]+sum1[i-2]-1;//前两个的和-1
sum2[i]=sum2[i-1]+sum2[i-2]+1;//前两个的和+1
这道题刚开始想的是用数学方法,但发现,数学方法漏洞百出,会有信息丢失的情况。所以还是老老实实整数组的写。
#include<cstdio>
#define ll long long
using namespace std;
ll a,n,m,x,t;
ll sk,tk,ans;
ll suma[30000];
ll sumb[30000];
int main(void)
{
scanf("%lld%lld%lld%lld",&a,&n,&m,&x);
suma[3]=2;
suma[2]=1;
if(x==1 || x==2){
printf("%lld",a);
return 0;
}
for(int i=4;i<n;i++){
suma[i]=suma[i-1]+suma[i-2]-1;
sumb[i]=sumb[i-1]+sumb[i-2]+1;
}
t=(long long)(m-suma[n-1]*a)/sumb[n-1];
if((m-suma[n-1]*a)%sumb[n-1]!=0){
printf("No answer.");
return 0;
}
printf("%lld",a*suma[x]+t*sumb[x]);
}
T2:
样例输入:
10 3 1 -6 1 7 5 -2 5 -100 10
样例输出:
16
题解:
本来是一道DP版题,但是它的空间限制使这道题不得不将数组滚动起来。
或者像这样(一种很妙的写法):
in(a);
s1=a;
s2+=a;
maxx=maxx>s1?maxx:s1;
maxx=maxx>s2?maxx:s2;
if(s1>s2)s2=s1;
这个样子既简单明了便于思考,而且不错(滑稽)
#include<cstdio>
#define ll long long
#include<cstring>
#include<string>
using namespace std;
ll s1,s2,a,maxx;
int n;
template <typename T>inline void in(T &x){
T ch=getchar(),xx=0,fw=1;
while(!isdigit((int)ch)){if(ch=='-')fw=-1;ch=getchar();}
while(isdigit((int)ch)){xx=(xx<<1)+(xx<<3)+ch-'0';ch=getchar();}
x=xx*fw;
}
int main(void)
{
scanf("%d",&n);
maxx=-999999999;
for(int i=1;i<=n;i++){
in(a);
s1=a;
s2+=a;
maxx=maxx>s1?ma