Gym100812 L 扩展欧几里得
2.0 s
256 MB
standard input
standard output
They were all dead. The final lunge was an exclamation mark to everything that had led to this point. I wiped my sword from the blood of Dragon and sheathed it. And then it was all over. Devastated, I came out of the empty castle and wandered somewhere along a dirt road. But before I could think about what I would do now, I heard a piercing scream from behind: "Stop right now! Drop a sword and raise your hands up!". They were knights. Only knights scream like that before making a hit. If they had been bandits I would be already dead.
I turned back and saw two figures in heavy armor rushing towards me. They were Lancelot and Percival — two knights of the Round Table, known for their fast reprisal over renegades like me. In the Kingdom they were called the Cleaners. As for me, not the most suitable name: they usually left a lot of dirt.
I almost instantly read their technique. Each of them was preparing for some time, then hit instantly, then was preparing again for the same time, then hit again, and so on, while their victim was not fallen. Lancelot spent n seconds to prepare, and Percival — m seconds. I was too tired and could parry a hit only if the previous one was done more than a second ago, and there were no powers to counter-attack at all. It was the sense that Lady Luck was really a hooker, and you were fresh out of cash. The knights knew their job and the first hit I wouldn't be able to parry would finish me off. My story wouldn't have a happy end.
The only line contains two integers separated by a space: n and m (1 ≤ n, m ≤ 2·109) — the intervals of time in seconds between hits of Lancelot and Percival correspondingly.
Output a single integer — the number of seconds from the beginning of the fight when the protagonist will be killed.
9 6
18
7 11
22 题意 两个人分别隔 n 和 m 秒砍一刀 主角每闪避一次攻击需要休息一秒 问主角在第几秒被砍死 解析 根据题意我们可以得到 |x*n-m*y|<=1
一共两组情况
第一种 |x*n-m*y|=0 x*n=m*y 最优解就是n和m的最小公倍数=n*m/gcd(n,m)
第二种 |x*n-m*y|=1 我们令 r = |x*n - m*y| 可以推出 r=gcd(n,m)*|(x*n/gcd(n,m)-(y*m/gcd(n,m)|=gcd(n,m)*k
所以差值r肯定是gcd(n,m)的倍数 当最大公约数不是1的时候第二种情况不存在
当最大公约数为1时 之前的方程|x*n-m*y|=1(x,y为正整数)可以转化为 n*x+m*y=1 (扩展欧几里得)
跑一边 扩展欧几里得算法 可以得出一组解(x0,y0)
我错认为最优解就是max(abs(n*x0),abs(y0*m))
交上去居然过了 可能数据比较水 有人模拟也过了。。。(想不通)
但是后来我又仔细想了想 扩展欧几里得算法 得出来的只是一组解 怎么能确定最优解是 max(abs(n*x0),abs(y0*m))?
难道就没有比他们更小的解吗?然后就想到最优解应该是|x*n|或者|m*y|越小越好 n>0,m>0所以|x|或|y|越小越好
因为 他们相差1 所以单独考虑一个x就好了 查阅资料得到了x的通项公式x=x0+k*m/gcd(n,m)
当x>0是 最小正整数解为 x%m 但并不能保证是绝对值最小的解 如果x%m<=m/2 x*n是最优解 反之(x-m)*n+1是最优解
当x<0时 最小负整数解为(x+m)%m 同理
我们再换个角度想 n*x+m*y=1
说明 n*x>0,m*y<0 或者 n*x<0,m*y>0
所以我们只需要求x的最小正整数解x' 和y的最小正整数解y'
相关博客
http://blog.csdn.net/zhjchengfeng5/article/details/7786595
最优解就是min(x'*n,y'*m)
而不用像上面所说的 去找x绝对值最小的解
思维一点一点的进步。。这应该是标准答案了吧。。。
AC代码1
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>
#include <queue>
#include <map>
#include <vector>
using namespace std;
const int maxn = +;
const int maxm = 1e4+;
const int inf = 0x3f3f3f3f;
const int mod = ;
const double epx = 1e-;
typedef long long ll;
const ll INF = 1e18;
ll n,m,t;
ll exgcd(ll a,ll b,ll &x,ll &y) //&引用符号,修改x,y,函数返回的是a,b的最大公约数
{
if(b==)
{
x=;
y=;
return a;
}
ll r=exgcd(b,a%b,x,y); //递归下去
ll temp=x;
x=y;
y=temp-a/b*y;
return r;
}
int main()
{
cin>>n>>m;
ll x,y;
ll g=exgcd(n,m,x,y);
ll ans=n*m/g;
if(n==||m==)
{
if(n==m)
cout<<""<<endl;
else
cout<<""<<endl;
return ;
}
if(g==)
ans=min(ans,max(abs(x*n),abs(y*m)));
cout<<ans<<endl;
}
AC代码2
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>
#include <queue>
#include <map>
#include <vector>
using namespace std;
const int maxn = +;
const int maxm = 1e4+;
const int inf = 0x3f3f3f3f;
const int mod = ;
const double epx = 1e-;
typedef long long ll;
const ll INF = 1e18;
ll n,m,t;
ll exgcd(ll a,ll b,ll &x,ll &y) //&引用符号,修改x,y,函数返回的是a,b的最大公约数
{
if(b==)
{
x=;
y=;
return a;
}
ll r=exgcd(b,a%b,x,y); //递归下去
ll temp=x;
x=y;
y=temp-a/b*y;
return r;
}
ll abss(ll a)
{
if(a<)
return -a;
else
return a;
}
int main()
{
cin>>n>>m;
ll x,y;
ll g=exgcd(n,m,x,y);
ll ans=n*m/g;
if(n==||m==)
{
if(n==m)
cout<<""<<endl;
else
cout<<""<<endl;
return ;
}
if(g==)
{
if(x>)
{
x=x%m;
if(x>m/)
{
x-=m;
ans=min(ans,abss(x*n)+);
}
else
ans=min(ans,x*n);
}
else if(x<)
{
x=x%m;
if(abss(x)>m/)
{
x+=m;
ans=min(ans,x*n);
}
else
ans=min(ans,abss(x*n)+);
}
}
cout<<ans<<endl;
}
AC代码3(最完美)
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>
#include <queue>
#include <map>
#include <vector>
using namespace std;
const int maxn = +;
const int maxm = 1e4+;
const int inf = 0x3f3f3f3f;
const int mod = ;
const double epx = 1e-;
typedef long long ll;
const ll INF = 1e18;
ll n,m,t;
ll exgcd(ll a,ll b,ll &x,ll &y) //&引用符号,修改x,y,函数返回的是a,b的最大公约数
{
if(b==)
{
x=;
y=;
return a;
}
ll r=exgcd(b,a%b,x,y); //递归下去
ll temp=x;
x=y;
y=temp-a/b*y;
return r;
}
int main()
{
cin>>n>>m;
ll x,y;
ll g=exgcd(n,m,x,y);
ll ans=n*m/g;
if(n==||m==)
{
if(n==m)
cout<<""<<endl;
else
cout<<""<<endl;
return ;
}
if(g==)
{
ll ans1=((x%m+m)%m)*n;
ll ans2=((y%n+n)%n)*m;
ans=min(ans,min(ans1,ans2));
}
cout<<ans<<endl;
}
一开始没看题意看样例认为只是单纯的输出最大值的二倍,读一遍题暴力模拟了一发,超时了。
为什么人家的模拟就过了。。应该超时的啊 只能说数据水了
引发了这么长的血案。。
Gym100812 L 扩展欧几里得的更多相关文章
- POJ 1061 青蛙的约会 扩展欧几里得
扩展欧几里得模板套一下就A了,不过要注意刚好整除的时候,代码中有注释 #include <iostream> #include <cstdio> #include <cs ...
- poj 1061 扩展欧几里得解同余方程(求最小非负整数解)
题目可以转化成求关于t的同余方程的最小非负数解: x+m*t≡y+n*t (mod L) 该方程又可以转化成: k*L+(n-m)*t=x-y 利用扩展欧几里得可以解决这个问题: eg:对于方程ax+ ...
- hdu 5512 Pagodas 扩展欧几里得推导+GCD
题目链接 题意:开始有a,b两点,之后可以按照a-b,a+b的方法生成[1,n]中没有的点,Yuwgna 为先手, Iaka后手.最后不能再生成点的一方输: (1 <= n <= 2000 ...
- 【数论】【扩展欧几里得】Codeforces 710D Two Arithmetic Progressions
题目链接: http://codeforces.com/problemset/problem/710/D 题目大意: 两个等差数列a1x+b1和a2x+b2,求L到R区间内重叠的点有几个. 0 < ...
- 扩展欧几里得 POJ 1061
感觉这道题目的数据好水啊...我的代码我都觉得姿势特别奇怪...竟然还过了... 好吧,原来不是姿势奇怪,而是逆元需要用的时候是余数也需要的时候,这里的余数是不需要的,所以就AC了 就说一下碰到的问题 ...
- pku 1061 青蛙的约会 扩展欧几里得
青蛙的约会Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 120482 Accepted: 25449Description 两只青 ...
- POJ1061 青蛙的约会(扩展欧几里得)
题目链接:http://poj.org/problem?id=1061 青蛙的约会 Time Limit: 1000MS Memory Limit: 10000K Total Submission ...
- [P1516]青蛙的约会 (扩展欧几里得/中国剩余定理?)
每日做智推~ 一看就是一道数学题. 再看是一道公约数的题目. 标签是中国孙子定理. 题解是扩展欧几里得 (笑) 一开始没看数据范围 只有50分 开一个longlong就可以了 #include< ...
- J - 青蛙的约会(扩展欧几里得)
https://vjudge.net/contest/218366#problem/J 第一步追及公式要写对:y+nk-(x+mk)=pL => (n-m)k+lp=x-y 可以看出扩展欧几里得 ...
随机推荐
- Codeforces Round #230 (Div. 1)
A: 题意:给你一个半径为n的圆 求最少阻塞多少个点 才能使所以圆内及圆上的点 都不与外边的点相连 相连是距离为1 只算整数点 这题定住x,y依次递减 判断一下是否4-connect 这个意思就是 ...
- 移动端rem单位用法
1.rem(font size of the root element)是指相对于根元素的字体大小的单位,em(font size of the element)是指相对于父元素的字体大小的单位.它们 ...
- robotframework + python2.7.9 + selenium 2.44.0 + selenium2library1.7 测试环境搭建成功!
真心不容易呀!开源软件搭建挺麻烦的,各种组件未必要使用最新的版本:有些最新版本反而不兼容.需要仔细看官方说明书来进行搭建(官方网站都是英文),所以闹得重新安装了几次. 先上测试用例通过的图:
- 短视频SDK用于旅游行业
超级简单易用的短视频SDK来自RDSDK.COM.锐动天地为开发者提供短视频编辑.视频直播.特效.录屏.编解码.视频转换,等多种解决方案,涵盖PC.iOS.Android多平台.以市场为导向,不断打磨 ...
- dede自定义表单放首页出错的解决办法
一.当自定义表单放首页提交的时候跳出这个页面怎么解决 二.解决办法 可能有多个from表单提交出错,也就是代码冲突的意思,只要把代码检查好,from提交不要重复冲突就可以了
- JS 中的 JSON
JSON是JavaScript Object Notation的缩写,它是一种数据交换格式. 在JSON出现之前,大家一直用XML来传递数据.因为XML是一种纯文本格式,所以它适合在网络上交换数据.X ...
- vue2.0 组件化
简单理解其实组件就是制作自定义的标签,这些标签在HTML中是没有的. 组件注册的是一个标签,而指令注册的是已有标签里的一个属性.在实际开发中我们还是用组件比较多,指令用的比较少. <!DOCTY ...
- (转)淘淘商城系列——SSM框架整合之表现层整合
http://blog.csdn.net/yerenyuan_pku/article/details/72721120 上文我们一起学习了Service层的整合,本文将教大家如何整合表现层. 我们在t ...
- fabric的安装
https://blog.csdn.net/lepton126/article/details/79148027
- h5开发app,移动端 click 事件响应缓慢的解决方案
造成点击缓慢的原因 从点击屏幕上的元素到触发元素的 click 事件,移动浏览器会有大约 300 毫秒的等待时间.为什么这么设计呢? 因为它想看看你是不是要进行双击(double tap)操作. 使用 ...