POJ 1061 解题报告

2024-03-29 08:18
文章标签 报告 poj 解题 1061

本文主要是介绍POJ 1061 解题报告,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这道题是Extended Euclidean Algorithm的应用。可以看

链接1(extended euclidean algorithm):http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm

链接2(Bezout's Identity):http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity

这里的代码是按照wikipedia上链接1的描述写的。


首先假设当两只青蛙相遇时,都跳了K步(根据题意,它们跳得步数是一样的),并且第一只青蛙比第二只青蛙多跳了c圈(c可以为负数),这样,我们有:

x + Km - (y + Kn) = cL ,即:(x - y) + K(m - n) = cL,亦即:

K(n - m) + cL = (x - y)      (以下称作原方程)

这样就转化为了一个可以应用Extended Euclidean Algorithm的问题。

Extended Euclidean Algorithm可以求出ax + by = gcd(a, b)的一个整数解(x0, y0)。然后根据链接2,我们知道这个方程的所有整数解为(x, y) = (x0 + kb/g, y - ka/g)。(这点比较好验证,带进去后面部分就都消掉了)。其中k是任意整数,g=gcd(a,b).

我们让a = n - m, b = L,那么我们可以根据上述extend euclidean algorithm得到一组解(x0, y0)。这个算法还可以附带得到g = gcd(a, b)。(所以不用单独跑gcd算法)。

很容易看出,既然左边能被g整除,那么右边的(x-y)也必须能够被g整除,否则原方程无解。

我们将原方程右边记做R,即R = x - y。

否则,我们可以得到这个方程的所有解: (x, y) = (R / g * x0 + kb/g, R/g * y0 + kb/g)。

按照问题,我们只关心第一项,即K = R / g * x0 + kb/g。我们要求的是这样一组K中最小的非负整数。

做法是先让K=0,求出k(这样的整数k不一定存在,但这样我们就可以求出使得K最接近0的k),然后求K。

k = (- R/g *x0) / (b/g)

然后K = R / g * x0 +  (- R/g *x0) / (b/g) * b/ g。

注:上述公式中都是整数运算。

我们用P = R/g, Q = b / g,x0 = mQ + r带入上述简化表达式,有:

K = P * (mQ + r) - P (mQ + r) / Q * Q = P*(mQ + r) - P m Q = P*r = P * (x0 % Q) = (P*x0) % Q。

即K是P*x0对Q的余数。

剩下的值得注意的就是让Q为正数就好了(可以直接取Q的绝对值,因为这时相当于k的绝对值变了)。


程序如下:

1061Accepted216K0MSC++1906B

/* 
ID: thestor1 
LANG: C++ 
TASK: poj1061 
*/
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <limits>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <cassert>using namespace std;void extend_gcd(long long a, long long b, long long &g, long long &x0, long long &y0)
{long long r0 = a, r1 = b, s0 = 1, s1 = 0, t0 = 0, t1 = 1;long long q2, r2, s2, t2;while (r1 != 0){q2 = r0 / r1;r2 = r0 - r1 * q2; // r0 % r1s2 = s0 - s1 * q2;t2 = t0 - t1 * q2;r0 = r1, r1 = r2;s0 = s1, s1 = s2;t0 = t1, t1 = t2;}// cout << a << " * " << s0 << " + " << b << " * " << t0 << " == " << r0 << "(GCD(" << a << ", " << b << "))" << endl;g = r0;x0 = s0;y0 = t0;
}int main()
{long long x, y, m, n, L;while (cin >> x >> y >> m >> n >> L){// extend_gcd(240, 46);// x + km - (y + kn) = cL // =>// (x - y) + k(m - n) = cL// =>// k(n - m) + cL = (x - y)long long a = n - m, b = L, R = x - y;long long g, x0, y0;extend_gcd(a, b, g, x0, y0);// cout << "a: " << a << ", b: " << b << ", R: " << R << endl;// cout << "g: " << g << ", x0: " << x0 << ", y0: " << y0 << endl;if (R % g != 0){cout << "Impossible" << endl;}else{long long k = R / g * x0;long long add = b / g;if (add < 0){add = -add;}cout << (k % add + add) % add << endl;}}return 0;
}


这篇关于POJ 1061 解题报告的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/858085

相关文章

Java使用POI-TL和JFreeChart动态生成Word报告

《Java使用POI-TL和JFreeChart动态生成Word报告》本文介绍了使用POI-TL和JFreeChart生成包含动态数据和图表的Word报告的方法,并分享了实际开发中的踩坑经验,通过代码... 目录前言一、需求背景二、方案分析三、 POI-TL + JFreeChart 实现3.1 Maven

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

poj 1511 Invitation Cards(spfa最短路)

题意是给你点与点之间的距离,求来回到点1的最短路中的边权和。 因为边很大,不能用原来的dijkstra什么的,所以用spfa来做。并且注意要用long long int 来存储。 稍微改了一下学长的模板。 stack stl 实现代码: #include<stdio.h>#include<stack>using namespace std;const int M

poj 3259 uva 558 Wormholes(bellman最短路负权回路判断)

poj 3259: 题意:John的农场里n块地,m条路连接两块地,w个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。 任务是求你会不会在从某块地出发后又回来,看到了离开之前的自己。 判断树中是否存在负权回路就ok了。 bellman代码: #include<stdio.h>const int MaxN = 501;//农场数const int

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];

poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)

题目很麻烦,因为不熟悉最小生成树的算法调试了好久。 感觉网上的题目解释都没说得很清楚,不适合新手。自己写一个。 题意:给你点的坐标,然后两点间可以有两种方式来通信:第一种是卫星通信,第二种是无线电通信。 卫星通信:任何两个有卫星频道的点间都可以直接建立连接,与点间的距离无关; 无线电通信:两个点之间的距离不能超过D,无线电收发器的功率越大,D越大,越昂贵。 计算无线电收发器D

poj 1502 MPI Maelstrom(单源最短路dijkstra)

题目真是长得头疼,好多生词,给跪。 没啥好说的,英语大水逼。 借助字典尝试翻译了一下,水逼直译求不喷 Description: BIT他们的超级计算机最近交货了。(定语秀了一堆词汇那就省略吧再见) Valentine McKee的研究顾问Jack Swigert,要她来测试一下这个系统。 Valentine告诉Swigert:“因为阿波罗是一个分布式共享内存的机器,所以它的内存访问