UVa 106/POJ 1305 Fermat vs. Pythagoras(数论&勾股数)

106 - Fermat vs. Pythagoras

Time limit: 3.000 seconds

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=115&page=show_problem&problem=42

http://poj.org/problem?id=1305


题意:

求≤N的本原勾股数组(PPT)的组数和≤N的非勾股数的个数。


思路:

参考《数论概论》P10的如下定理:


则对所有满足3s√(2n-1),1t≤max{ s-2 , √(2n-s^2) },gcd(s,t)=1的奇数s,t,求PPT和对应范围内的派生勾股数(本原勾股数组(a,b,c)的派生勾股数组为(ka,kb,kc),k>1),然后标记已出现过的数。

最后统计未标记的数的个数即可。

复杂度:O(NlogN)


完整代码:

/*UVa: 0.192s*/
/*POJ: 0ms,1136KB*/

#include <cstdio>
#include <cstring>
#include <cmath>
const int maxn = 1000001;

bool vis[maxn];

int gcd(int a, int b) {return b ? gcd(b, a % b) : a;}

int main()
{
	int n, s, t, maxs, maxt, i, a, b, c;
	while (~scanf("%d", &n))
	{
		int cnt = 0;//PPT的组数
		memset(vis, 0, sizeof(vis));

		//循环生成所有的s和t,根据公式,s的最大值maxs<=√(2n-1)
		maxs = (int)sqrt((double)((n << 1) - 1));
		for (s = 3; s <= maxs; s += 2)
		{
			//求出t的最大值maxt,maxt<=s-2 && maxt<=√(2n-s^2)
			maxt = (int)sqrt((double)((n << 1) - s * s));
			if (s - 2 < maxt) maxt = s - 2;
			for (t = 1; t <= maxt; t += 2)
			{
				if (gcd(s, t) == 1)
				{
					++cnt;
					a = s * t;
					b = (s * s - t * t) >> 1;
					c = (s * s + t * t) >> 1;

					//标记PPT及其派生勾股数
					for (i = 1; c * i <= n; ++i)
						vis[a * i] = vis[b * i] = vis[c * i] = true;
				}
			}
		}
		printf("%d ", cnt);

		//统计没有出现过的数的个数
		cnt = 0;
		for (i = 1; i <= n; ++i)
			if (!vis[i]) ++cnt;
		printf("%d\n", cnt);
	}
	return 0;
}

&lt;think&gt;我们有一个链接错误:ld: cannot find -lpng12 和 collect2: error: ld returned 1 exit status。 这明确指示在链接阶段,链接器(ld)无法找到名为 libpng12 的库文件(通常为 libpng12.so 或 libpng12.a)。 因此,用户缺少的是 libpng12 这个库文件,具体是针对目标平台(这里是ARM架构)的版本。 但是,根据之前的对话,用户已经在一个交叉编译环境中工作(使用arm-buildroot-linux-gnueabi工具链),所以我们需要确保这个库在交叉编译工具链的sysroot中可用。 因此,回答应集中在缺少的文件是什么以及如何解决这个缺失。 &lt;/think&gt;您的错误信息明确表示链接器(`ld`)在编译过程中无法找到名为 **`libpng12` 的库文件**,导致链接失败并返回退出状态 1。以下是详细解析: ### 缺失的核心文件: 1. **动态链接库文件**:`libpng12.so`(共享对象文件) - 这是 PNG 图像处理库的 1.2 版本运行时文件 - 默认应位于工具链的库目录:`.../arm-buildroot-linux-gnueabi/lib/` 或 `/usr/lib/` - 检查是否存在:`find / -name libpng12.so* 2&gt;/dev/null` 2. **静态链接库文件**:`libpng12.a`(归档文件) - 编译时需要的静态库版本 - 通常与动态库位于同一目录 3. **符号链接文件**: - 链接器可能要求 `libpng12.so` 指向具体版本(如 `libpng12.so.0.49.0`) - 检查符号链接:`ls -l /path/to/toolchain/lib/libpng12*` ### 根本原因: - **交叉编译环境缺失**:您的 ARM 工具链(`arm-buildroot-linux-gnueabi`)未包含 PNG 库的 ARM 架构版本 - **版本过时**:`libpng12` 是较旧版本(当前主流为 libpng16),可能已被系统移除 ### 解决方案: 1. **安装 ARM 版 libpng12**: ```bash # 查找 Buildroot 包(需在 Buildroot 目录) make menuconfig # 进入 Target packages &rarr; Libraries &rarr; Graphics &rarr; 选中 libpng &rarr; 指定版本 1.2.x make toolchain-rebuild ``` 2. **手动添加库文件**: - 从其他 ARM 设备复制 `libpng12.so` 和 `libpng12.a` 到工具链的库目录: ```bash cp libpng12.* /home/wangrui66/.../arm-buildroot-linux-gnueabi/lib/ ``` 3. **强制链接兼容版本**(临时方案): ```bash ln -s /usr/lib/libpng.so /home/wangrui66/.../lib/libpng12.so ``` ### 验证是否解决: 重新编译时添加库搜索路径: ```bash gcc -L/home/wangrui66/.../arm-buildroot-linux-gnueabi/lib -lpng12 ... ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值