题解
- 这显然就是个找规律的题目,让我们来看一组数据
-
6 20
2 4 8 16 20 19 19 18 16 12 16 20 19 19 18 16 12 16 20 19
- 我们会发现,当k被填满后,每m+1个就是一个循环,那么m+1就是循环节
- 然后两个19+1=20后,每个往后一个都是对应的2+18=20,4+16=20,8+12=20...
- 最后我们就可以处理出前面的,然后得到后面的就行了
代码
1 #include <cstdio>
2 #include <iostream>
3 #define ll long long
4 #define N 10010
5 using namespace std;
6 ll n,m,k,w,f[N],g[N];
7 int main()
8 {
9 scanf("%lld%lld%lld",&n,&m,&k),f[0]=g[0]=1;
10 if (m==1) { printf("0"); return 0;}
11 for (int i=1;i<=n;i++)
12 {
13 f[i]=min(k-g[i-1],g[i-1]-((i>=m)?f[i-m]:0)),g[i]=g[i-1]+f[i]-((i>=m)?f[i-m]:0);
14 if (f[i]+g[i-1]==k) { w=i; break; }
15 }
16 if (w==n||!w) printf("%lld",g[n]);
17 else
18 {
19 if ((n%=m+1)<=w) n+=m+1;
20 if (n-m>=0) printf("%lld",k-f[n-m]); else printf("%lld",k);
21 }
22 }