https://vijos.org/p/1279
背景
期待这一份幸运,和一份冲劲,多么奇妙的际遇……。燕姿在演唱完绿光这首歌后,出给了姿迷一个考题。
北欧有一个传说!
人一生中能看见绿光!
他就一生都可以得到幸福!
描述
燕姿唱完这首歌,天上降落了一道绿光,在地上形成了一个矩形的映射,矩形的长为a,宽为b。燕姿向姿迷出了一个考题,谁能够把这个矩形绿光阵分成若干个正整数的正方形,谁的正方形边长之和最小,他就将得到燕姿的一个合影。姿迷们都很想得到合影,可是怎么分才最小呢?大家都束手无策,现在,这个问题交给你了。
歌迷X:呜呜呜,俺的语文不好,听不懂你在讲什么。
燕姿:别怕,其实这个问题可以简化为……
将边长为正整数a,b的长方形划分成若干边长均为正整数,每个正方形的边均平行于矩形的相应边,试求这些正方形边之和的最小值MIN。
(如果这个长方形可以分成N个正方形,其中每个边长为Ai,那么MIN=A1+A2+^^^+AN
注意,数组A中的元素可能相等)
格式
输入格式
一共10行
每行两个正整数,Ai,Bi
对于30%的数据,Ai,Bi<maxint
对于100%的数据,Ai,Bi<maxlongint;
输出格式
一共10行
每行一个整数,输出MINi
样例1
样例输入1
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
样例输出1
1
2
3
4
5
6
7
8
9
10
限制
每点1s
提示
对于样例,可全分长边长为一的正方形,并且可以证明找不到比其更优的分割方法;
加油吧,为了得到燕姿的合影(#17)
来源
孙燕姿
ans先加上min(a,b),原矩形可变成边长为 max(a,b),max(a,b)-min(a,b)的样子
依次进行下去,更相减损,最后的矩形的边长一定是gcd(a,b),且应只加一个
所以ans=a+b-gcd(a,b)
1 #include <algorithm> 2 #include <iostream> 3 4 using namespace std; 5 6 #define LL long long 7 LL gcd_(LL a,LL b) 8 { 9 if(a%b==0) return b; 10 return gcd_(b,a%b); 11 } 12 13 int main() 14 { 15 for(LL a,b,t=10;t--;) 16 { 17 cin>>a>>b; 18 cout<<a+b-gcd_(a,b)<<endl; 19 } 20 return 0; 21 }
1 #define LL long long 2 #include <algorithm> 3 #include <cstdio> 4 5 using namespace std; 6 7 LL n,m,ans,cnt; 8 9 int main() 10 { 11 for(int t=10;t--;ans=0) 12 { 13 scanf("%lld%lld",&n,&m); 14 if(n>m) swap(n,m); 15 for(;m&&n;m-=m/n*n) 16 { 17 if(n>m) swap(n,m); 18 ans+=n*(m/n); 19 } 20 printf("%lld\n",ans); 21 } 22 23 return 0; 24 }