POJ2908 Quantum 光搜+优先队列好题目

这是一道好题目啊,放假回头准备练练手的,发现是我弱爆了。。。首先一开始就大致确定好了思路,画了一会,发现优先队列直接贪心就可以的,接下来就敲了,一开始都用了字符串导致一直WA,做了一个下午把,后来发现了错的地方,然后接着TLE,然后看网上说是不要用STL的优先队列,自己写一个小顶堆,然后套了个模板,结果还是TLE,认为自己的模板错了,可是发现跟别人的一致,又弄到了现在,实在找不出哪里有问题,然后看题解了,发现了一篇转化着做的,把字符串转化成二进制的十进制数,这样就直接利用位运算来做,总算是A掉了,去尝试了记忆化搜索,因为转化后有状态标记的,试了几次,发现不行,就放弃了,一天就做了这一道题目。。。

参考了:戳这里

做法还是比较清晰的,画一画再大胆猜测一下,留个纪念,毕竟做了一天,题意说不清楚引用别人的:题目给出nop个操作,由N(什么都不做),S(置1),C(置0),F(反转)等基本操作组成,每一种操作会产生不同的热量。又给出nw组初始字符串和目标字符串,要求出将初始字符串转化成目标字符串至少需要产生的热量;有可能没有解,此时输出“NP”

直接bfs,类似于dfs的暴力枚举一样,队列循环,每一次都去扫一遍nop的所有操作,然后花费小的优先,暴力寻找,找到跳出,找不到就是没有答案的,同时还要标记此状态是否已经出现过了,每一个求答案都得要把状态标记数组清空,前几天因为用了memset总是TLE,坑了许久,这题目还是有点虚的,还好没有被坑

以后做题要提醒自己发现思路了,要先好好想想怎么样做最方便,不然也把自己绕醉了~

typedef struct Node {
	int val;
	int ss;
	friend bool operator<(Node x,Node y) {
		return x.val > y.val;
	}
};

int n,nop,nw;

int make_true[30 + 5],make_false[30 + 5],xo[30 + 5],w[30 + 5];

bool vis[1<<22];

priority_queue<Node > q;

void init() {
	memset(make_true,0,sizeof(make_true));
	memset(make_false,0,sizeof(make_false));
	memset(xo,0,sizeof(xo));
	memset(w,0,sizeof(w));
}

bool input() {
	while(cin>>n>>nop>>nw) {
		for(int i=0;i<nop;i++) {
			char s[20 + 5];
			scanf("%s %d",&s,&w[i]);
			for(int j=0;j<n;j++) {
				make_true[i] <<= 1;
				make_false[i] <<= 1;
				xo[i] <<= 1;
				make_false[i]++;
				if(s[j] == 'S')make_true[i]++;
				else if(s[j] == 'F')xo[i]++;
				else if(s[j] == 'C')make_false[i]--;
			}
		}
		return false;
	}
	return true;
}

int slove(char *s) {
	int len = strlen(s);
	int ret = 0;
	for(int i=0;i<len;i++) {
		ret <<= 1;
		if(s[i] == '1')ret++;
	}
	return ret;
}

int bfs(int start,int end) {
	memset(vis,false,sizeof(vis));
	while(!q.empty()) q.pop();
	Node s,e;
	s.val = 0;
	s.ss = start;
	q.push(s);
	while(!q.empty()) {
		s = q.top();
		q.pop();
		int pos = s.ss;
		if(vis[pos])continue;
		if(pos == end)return s.val;
		vis[pos] = true;
		for(int i=0;i<nop;i++) {
			int tmp = ((pos&make_false[i])|make_true[i])^xo[i];
			if(!vis[tmp]) {
				e.ss = tmp;
				e.val = s.val + w[i];
				q.push(e);
			}
		}
	}
	return -1;
}

void cal() {
	int q = nw;
	bool flag = false;

	while(q--) {
		char start[20 + 5],end[20 + 5];
		scanf("%s %s",start,end);
		if(flag)putchar(' ');
		else flag = true;
		int s = slove(start);
		int e = slove(end);
		int ans = bfs(s,e);
		if(ans < 0)printf("NP");
		else printf("%d",ans);
		//cout<<"-->";
	}
	puts("");
}

void output() {

}

int main() {
	int t;
	cin>>t;
	while(t--) {
		init();
		if(input())return 0;
		cal();
		output();
	}
	return 0;
}
时间: 2024-10-13 05:34:01

POJ2908 Quantum 光搜+优先队列好题目的相关文章

NYOJ 284 坦克大战 &amp;&amp; POJ 2312 Battle City (广搜+优先队列)

链接:click here~~ 题意: 描述 Many of us had played the game "Battle city" in our childhood, and some people (like me) even often play it on computer now. What we are discussing is a simple edition of this game. Given a map that consists of empty space

hdu 1242:Rescue(BFS广搜 + 优先队列)

Rescue Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 14   Accepted Submission(s) : 7 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description Angel was caught by the MOLIGPY

hdu 1026 Ignatius and the Princess I 广搜+优先队列+记录路径

Ignatius and the Princess I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 13414    Accepted Submission(s): 4232 Special Judge Problem Description The Princess has been abducted by the BEelzeb

HDU1180 诡异的楼梯 广搜 优先队列

Problem Description Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向. 比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向,再过一分钟它又回到了竖直方向.Harry发现对他来说很难找到能使得他最快到达目的地的路线,这时Ron(Harry最好的朋友)告诉Harry正好有一个魔法道具可以帮助他寻找这样的路线,而那个魔法道具上的咒语,正是由你纂写的. Input 测试数据有多组,每组的表

hdoj-1242-Rescue【广搜+优先队列】

Rescue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 21510 Accepted Submission(s): 7671 Problem Description Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is descri

HDU1026--Ignatius and the Princess I(BFS记录路径)

Problem Description The Princess has been abducted by the BEelzebub feng5166, our hero Ignatius has to rescue our pretty Princess. Now he gets into feng5166's castle. The castle is a large labyrinth. To make the problem simply, we assume the labyrint

深搜笔记

看搜索已经很久了,对于搜索的思想从原来的死记硬背到现在终于懂了一点其实也蛮不错吧,我自己先总结出来了几条关于在图里面深搜的几条方法,仅供参考: 首先:我们得知道深搜是什么,其次于广搜的区别是什么.然后又哪些模板 举一个深搜例子:red and black:这是初学者最常见到的题.对于这题我们所要考虑的就是一个'.'的个数,这个题先要找到@的位置,这个好办,直接: for(int i=0;i<m;i++) { for(int j=0;j<n;j++) { if(map[i][j]=='@') }

深搜1--城堡问题

深搜1--城堡问题 一.心得 这个题目的栈实现可以看一看 也是很基础的迷宫问题,也就是一个深搜 二.题目及分析 三.代码及结果 递归 1 #include <iostream> 2 #include <stack> 3 #include <cstring> 4 using namespace std; 5 int R,C; //行列数 6 int rooms[60][60]; 7 int color[60][60]; //房间是否染色过的标记 8 int maxRoom

UVA1203Argus(优先队列)

题目:UVA1203Argus(优先队列) 题目大意:给你多个项目,每个项目有它发生的周期和对应的Q_num值.现在要求给出前K个项目,时间优先,同一时刻发生的先输出Q_num值小的. 解题思路:先将这几个项目排下顺序,一开始这些项目的发生时间就是周期,按照时间优先和同一时刻的Q_num优先的原则将这个项目在priority_queue排下序,然后输出前K个.当输出某个项目的时候,同时也将这个项目的下个项目开始的时间更新在放入队列中.这样重复K次就可以了. 代码: #include <cstdi