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;}

当你能飞的时候就不要放弃飞

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

相关文章:

你感兴趣的文章:

标签云: