纪中暑假集训 2020.07.31【NOIP提高组】模拟 T1:【NOIP2015模拟11.3晚】次芝麻

【NOIP2015模拟11.3晚】次芝麻

Description

在这里插入图片描述

Input

在这里插入图片描述

Output

在这里插入图片描述

Sample Input

5 5 3

Sample Output

0
在这里插入图片描述

Data Constraint

在这里插入图片描述

反思&题解

比赛&正解思路: 刚开始手玩了几个样例,发现两个数每一次操作的变化规律为本身乘上2再与两个加起来的总和取模,接下来我来证明一下:
我们设每次操作中较小的数为x,较大的数为y,很显然两个数分别变成 2 x 2x 以及 y x y-x ,最后答案就是取最小的
因为x是较小的数,即使两个数相等,x也不会大于他们的总和, 2 x 2x 所以跟他们的总和取一下模的答案是不变的,如果取模的答案为0也就是说另一个数已经变成了0,每次操作都不会变了,对答案取min不会产生影响
又因为y变成的是 y x y-x ,将式子加上一个y再减去一个y的结果是不变的,即 2 y ( x + y ) = y x 2y-(x+y)=y-x ,又因为y是较大的那个数,所以 2 y 2y 是无论如何也不可能超过x和y的总和乘2的,所以 2 y / ( x + y ) 2y/(x+y) 的结果只有两种情况:得1余0,得1余某个数字(方便写我们表示成z),得2余0
余0的情况同理x取模为0的情况
而余z的情况,根据除法验算的方法可知, 1 ( x + y ) + z = 2 y 1(x+y)+z=2y ,即 x + y + z = 2 y x+y+z=2y ,即 z = 2 y x y z=2y-x-y ,化简得 z = y x z=y-x ,也就是余数等于下一次操作的结果
如果还有问题的朋友可以评论出来我再来解释
所以最后的答案就是 m i n ( 2 k n , 2 k m ) min(2^kn,2^km) ,注意这俩数都要取模
反思: 有时候手模样例出奇迹!!!

CODE

#include<bits/stdc++.h>
using namespace std;
long long n,m,k,mo;
long long power(long long x,long long y)
{
	long long tot=1;
	while (y)
	{
		if (y&1) tot=tot*x%mo;
		y>>=1;
		x=x*x%mo;
	}
	return tot;
}
int main()
{
	freopen("sesame.in","r",stdin);
	freopen("sesame.out","w",stdout);
	scanf("%lld%lld%lld",&n,&m,&k);
	mo=n+m;
	printf("%lld\n",min(n*power(2,k)%mo,m*power(2,k)%mo));
	return 0;
}

猜你喜欢

转载自blog.csdn.net/CMC_YXY/article/details/107714907