ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

POJ 1945 Power Hungry Cows

2022-06-20 19:01:27  阅读:137  来源: 互联网

标签:node return int Hungry step add POJ Cows false


Description

有两个数a、b,初始值分别为x、1,每次可以将a、b中的一个数与自身或另外一个进行乘、除运算,并将结果保存到a或b,求最少用多少次运算能得到x^P。 (P <= 20000)

Analysis

1、广度优先搜索
状态(a,b)代表(x^a, x^b),令a为二者中较大的数,从(a, b)可以转移到8个状态,即(2a, b)、(a+b,b)、(2b,b)、(a,2a)、(a,a+b)、(a,2b)、(a,a-b)、(a-b,a),分别将这8种状态加入队列继续进行搜索,直到a或b等于P。
2、A搜索
设计估价函数f(i) = g(i) + h(i),g(i)是当前步数。h(i)是当前状态到终点步数的预估值。
对于当前状态(a,b),当a小于P式,a成倍地增长(a
=2, 即x^a和自己不断地相乘)可以更快的到达P,然后再用减法进行微调, h(i) = log(P/a);当a > P时,由于无法确定减法的次数,为了使h小于实际值,设h(i) = 0。用(a,b,g,h)表示状态,每次取g + h最小的状态进行扩展。

Code

bfs + 剪枝

5312K 485MS

#include <iostream>
#include <queue>
using namespace std;
const int maxn = 20003, maxq = 700003, prime0 = 20101, prime1 = 97;
int n, n2, answer;
bool hashTable[prime0][prime1];
struct node{
	int a, b, step;
};
queue<node> q;
int gcd (int a, int b) { return b ? gcd (b, a % b) : a; }
bool add_node(int a,int b,int step)
{
	if (a == n || b == n)
		return true;
	if (a < b)
	{
		int temp = a;
		a = b;
		b = temp;
	}
	if (n % gcd (a, b)) return false;
	if (a > 2 * n) return false;
	if (a > n && b == 0) return false;
	if (a == b || a >= n2 || b >= prime1)
		return false;
	if (!hashTable[a][b])
	{
		hashTable[a][b] = true;
		q. push ({a, b, step});
	}
	return false;
}

int bfs() {
	n2 = n + prime1;
	add_node(1, 0, 0);
	while(!q.empty())
	{
		int a = q.front().a, b = q.front().b, step = q.front().step + 1;
		q.pop();
		if(add_node(a+a, b, step) ||
		   add_node(a+b, b, step) ||
		   add_node(b+b, b, step) ||
		   add_node(a, a+a, step) ||
		   add_node(a, a+b, step) ||
		   add_node(a, b+b, step) ||
		   add_node(a, a-b, step) ||
		   add_node(a-b, a, step))
		{
			answer = step;
			break;
		}
	}
	return 0;
}

int main()
{
	cin >> n;
	bfs();
	cout << answer;
	return 0;
}

A* + 剪枝

9776K 47MS

#include <iostream>
#include <queue>
using namespace std;
const int prime0 = 20101, prime1 = 1097;
int n, n2, ans;
bool hashTable[prime0 + prime1][prime1];
struct node{
	int a, b, g, h;
	bool operator< (const node &a) const {
		return g + h == a . g + a . h ? h > a . h : g + h > a . g + a . h;
	}
};
node now;
priority_queue<node> q;
int gcd (int a, int b) { return b ? gcd (b, a % b) : a; }
bool add_node(int a,int b) {
	if (a == n || b == n)
		return true;
	if (a < b) {
		int temp = a;
		a = b;
		b = temp;
	}
	if (a > 2 * n) return false;
	if (a > n && b == 0) return false;
	if (a == b) return false;
	if (n % gcd (a, b)) return false;
	if (a >= n2 || b >= prime1)
		return false;
	if (!hashTable[a][b]) {
		hashTable[a][b] = true;
		int h = 0, tx = a;
		while (tx < n) h ++, tx <<= 1;
		q. push ({a, b, now.g + 1, h});
	}
	return false;
}
int Astar() {
	n2 = n + prime1;
	q. push({1, 0, 0, 0});
	hashTable[1][0] = true;
	while(!q.empty()) {
		now = q.top();
		int a = now.a, b = now.b;
		q.pop();
		if(add_node(a+a, b) || add_node(a+b, b) || add_node(b+b, b) || add_node(a, a+a) ||
		   add_node(a, a+b) || add_node(a, b+b) || add_node(a, a-b) || add_node(a-b, a)) {
			ans = now.g + 1;
			break;
		}
	}
	return 0;
}
int main() {
	cin >> n;
	Astar();
	cout << ans;
	return 0;
}

标签:node,return,int,Hungry,step,add,POJ,Cows,false
来源: https://www.cnblogs.com/Zforw/p/16394356.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有