| ||||||||||
| 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 | |||||||||
怎么没人帮忙看一下吗?In Reply To:终于过了,两天啊,真不容易,不过还是很奇怪最开始写的优先队列加广搜为什么会错,谁能帮忙看一下? Posted by:ACM06021fly at 2006-10-13 17:31:53 > #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