【校内互测】Sunshine's book(找规律)
Sunshine’s book(book.cpp)
【问题描述】
宇宙金牌Sunshine是一个追求完美的人。有一天他觉得小F桌子上摆着的两摞书对于他来说并不完美,他想使它们的数量更加完美,于是他采用了以下方法:假设两摞书的数量分别是a和b(a<=b),那么他会从第二摞书中拿出a本放到第一摞书中。
也就是说书堆(a,b)(a<=b)会变成(a+a,b-a),a>b时类似。
为了使书堆变得完美,机智的Sunshine进行了k次操作。他想知道经过了k次操作之后数量较少的书堆里会有多少书,并且Sunshine大爷并不想给你太多内存,他认为那样并不完美。
【输入格式】
一行三个整数a,b,k。
【输出格式】
一个整数代表 k 次搬书后较少的那一堆有多少书。
【样例输入】
4 7 2
【样例输出】
5
【数据规模及约定】
对于30%的数据,k<=10^6
另外存在10%的数据,a=1
对于100%的数据a,b,k<=10^9,保证a<=b
———————————————————————————————————
【题解】【找规律】
【考虑a一次操作后会变成什么 (a<=b)a -> 2*a, (a>b) a -> a-b = 2*a-(a+b)
综上:a -> 2*a%(a+b)】
【所以,进行K次变换,就是a'=2^k*a%(a+b),b'=a+b-a',取min即可】
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long a,b,k;
long long poww(int x,long long q,long long mod)
{
if(q==0) return 1;
if(q==1) return x%mod;
if(q==2) return x*x%mod;
if(!(q%2))
{
long long sum=poww(x,q/2,mod)%mod;
return sum*sum%mod;
}
else
{
long long sum=poww(x,q/2,mod)%mod;
return sum*sum*x%mod;
}
}
int main()
{
freopen("book.in","r",stdin);
freopen("book.out","w",stdout);
scanf("%lld%lld%lld",&a,&b,&k);
long long p=a+b,sum=poww(2,k,p);
a=a*sum%p;
b=(p-a)%p;
printf("%lld\n",min(a,b));
return 0;
}
既然无能更改,又何必枉自寻烦忧