| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
终于过了,两天啊,真不容易,不过还是很奇怪最开始写的优先队列加广搜为什么会错,谁能帮忙看一下?#include<cstdio>
#include<memory.h>
#include<algorithm>
using namespace std;
#define SIZE 5000000
unsigned clear[21] = {0x0,0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFB,0xFFFFFFF7,0xFFFFFFEF,
0xFFFFFFDF,0xFFFFFFBF,0xFFFFFF7F,0xFFFFFEFF,0xFFFFFDFF,
0xFFFFFBFF,0xFFFFF7FF,0xFFFFEFFF,0xFFFFDFFF,0xFFFFBFFF,
0xFFFF7FFF,0xFFFEFFFF,0xFFFDFFFF,0xFFFBFFFF,0xFFF7FFFF}; //清零整数某一位要用
struct Queue{
int value;
int f;
}queue[SIZE];
int tail,len;
int flag[1050000];
void exch(int i,int j) //交换队列中的元素
{
int tv = queue[i].value;
int tf = queue[i].f;
queue[i].value = queue[j].value;
queue[i].f = queue[j].f;
queue[j].value = tv;
queue[j].f = tf;
}
void push(int vl,int s) //入堆操作
{
queue[++tail].value = vl;
queue[tail].f = s;
int k = tail;
while(k > 1){
if(queue[k].value < queue[k/2].value)
exch(k,k/2),k /= 2;
else
break;
}
}
void pop(int &vl,int &f) //出堆操作
{
vl = queue[1].value;
f = queue[1].f;
queue[1].f = queue[tail].f ;
queue[1].value = queue[tail--].value ;
int k = 1,e;
while(k*2 <= tail){
e = 2*k;
if(queue[e+1].value < queue[e].value && e+1 <= tail)
e++;
if(queue[e].value < queue[k].value)
exch(k,e),k = e;
else
break;
}
}
struct Op{
char id[21];
int val;
}op[35];
int nop;
int adjust(int f,int j) //根据操作序列计算操作结果,用整数保存状态,所以用位运算
{
int t;
for(int i = 0; i < len; i++){
if(op[j].id[i] == 'N')
continue;
if(op[j].id[i] == 'C')
f = f&clear[len-i]; //清零
else{
t = 1 << (len-i-1);
if(op[j].id[i] == 'F')
f = f^t; //取反
else
f = f|t; //置1
}
}
return f;
}
int bfs(int s,int t) //开始广搜
{
int i;
tail = 0;
memset(flag,-1,sizeof(flag)); //flag记录某一状态是否出现过,出现过的话记录其出现所花费的最小费用
push(0,s);
flag[s] = 0;
while(tail > 0){
int tv,tf;
pop(tv,tf);
for(i = 0; i < nop; i++){
int ttv = tv + op[i].val;
int ttf = adjust(tf,i); //调整状态
if(ttf == t)
return ttv;
if(flag[ttf] == -1 || flag[ttf] > ttv){ //如果某状态出现过,现在再次出现且花费比以前出现的大或相等,就没有必要再入队列了。
flag[ttf] = ttv;
push(ttv,ttf);
}
}
}
return -1;
}
bool cmp(const Op &a,const Op &b)
{
return a.val < b.val;
}
int main()
{
int T,nw,i,out[21],s,t,j;
char ts[21];
for(scanf("%d",&T); T; T--){
scanf("%d%d%d",&len,&nop,&nw);
for(i = 0; i < nop; i++)
scanf("%s%d",op[i].id,&op[i].val);
sort(op,op+nop,cmp); //对各种操作按花费从小到大排一下序。
for(i = 0; i < nw; i++){
scanf("%s",ts);
s = 0;
for(j = 0; j < len; j++)
s = s*2+ts[j]-'0';
scanf("%s",ts);
t = 0;
for(j = 0; j < len; j++)
t = t*2+ts[j]-'0';
if(s == t)
out[i] = 0; //如果源和目标相等,则花费为0
else
out[i] = bfs(s,t);
}
if(out[0] == -1) //以下为输出操作。
printf("NP");
else printf("%d",out[0]);
for(i = 1; i < nw; i++)
if(out[i] == -1)
printf(" NP");
else
printf(" %d",out[i]);
printf("\n");
}
return 0;
}
Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator