UVa 10976 Fractions Again?!

本文介绍了一个解决特定分数分解问题的高效算法。通过分析输入整数 k,算法能够快速找出所有符合条件的整数对 (x, y),使得分数 k 可以表示为 x/y 的形式,并提供详细步骤和代码实现,旨在优化时间和空间效率。

Problem A: Fractions Again?!

Time limit: 1 second

It is easy to see that for every fraction in the form  (k > 0), we can always find two positive integers x and yx ≥ y, such that: 

.

Now our question is: can you write a program that counts how many such pairs of x and y there are for any given k?

Input

Input contains no more than 100 lines, each giving a value of k (0 < k ≤ 10000).

Output

For each k, output the number of corresponding (xy) pairs, followed by a sorted list of the values of x and y, as shown in the sample output.

Sample Input

2
12

Sample Output

2
1/2 = 1/6 + 1/3
1/2 = 1/4 + 1/4
8
1/12 = 1/156 + 1/13
1/12 = 1/84 + 1/14
1/12 = 1/60 + 1/15
1/12 = 1/48 + 1/16
1/12 = 1/36 + 1/18
1/12 = 1/30 + 1/20
1/12 = 1/28 + 1/21
1/12 = 1/24 + 1/24


Problemsetter: Mak Yan Kei

#include <cstdio>
#include <vector>
using namespace std;



int main()
{
	int k;
	/*
	while(scanf("%d",&k) == 1)
	{
		// 第一个数字遍历[2k,k^2+k], 第二个数字遍历[k+1,2k];
		long long x = 2*k;
		long long y = 2*k;
		long long upper_x = k*k+k;
//		printf("x: %lld y: %lld upper_x:%lld\n", x, y, upper_x);
		vector<pair<int,int> > my_array; 
		while(x <= upper_x && y >= k+1)
		{
			int result = x*y/(x+y);
			int reminder = (x*y) % (x+y);
//			printf("result: %d x: %lld y :%lld\n", result, x, y);
			if(k == result && reminder == 0)
			{
				my_array.push_back(pair<int,int>(x, y));
				x++;
				y--;
			}
			else if(k > result)
			{
				x++;
			}	
			else if(k < result || (k == result && reminder > 0))
			{
				y--;
			}
		}

		printf("%d\n", my_array.size());
		for(int i = my_array.size()-1; i >= 0; i--)
		{
			printf("1/%d = 1/%d + 1/%d\n", k, my_array[i].first, my_array[i].second);
		}					
	}*/
/*
	// 记录所有可能的情况
	for(int i = 1; i <= 10000; i++)
		my_table[i] = vector<pair<int,int> >();

	long long upper_x = 10000*10000 + 10000;
//	long long upper_x = 10000;
	for(long long x = 2; x <= upper_x; x++)
	{
		for(long long y = 2; y <= x; y++)
		{
			long long result = x*y / (x+y);
			long long reminder = (x*y) % (x+y);
			if(result > 10000)	
				break;
			if(reminder == 0)
			{
				my_table[result].push_back(pair<int,int>(x, y));				
			}
		}
	}
	printf("finish\n");
	while(scanf("%d", &k) == 1)
	{
		printf("%d\n", my_table[k].size());
		for(int i = my_table[k].size()-1; i >= 0; i--)
                {
                        printf("1/%d = 1/%d + 1/%d\n", k, my_table[k][i].first, my_table[k][i].second);
                }
	}		
*/
		
	while(scanf("%d", &k) == 1)
	{
		vector<pair<int,int> > my_array;
		for(int y = k + 1; y <= 2*k; y++)	
		{
			int result = k*y / (y-k);
			int reminder = k*y % (y-k);
			if(reminder == 0)
			{
				my_array.push_back(pair<int,int>(result, y));
			}
		}
		printf("%d\n", my_array.size());
		for(int i = 0; i < my_array.size(); i++)
		{
			printf("1/%d = 1/%d + 1/%d\n", k, my_array[i].first, my_array[i].second);
		}
	}
	return 0;	
}


自己写的程序TLE,虽然已经得到x的范围为(2k, k^2+k), y的范围为(k+1, 2k). 直接在这个范围内枚举x,y. 超时
后来看了答案,发现可以枚举y, 因为已知k, 可以算出x. 很巧妙。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值