Uvaoj10603(BFS + 判断条件是重点)

来源:互联网 发布:域名评价 编辑:程序博客网 时间:2024/04/29 23:54

Uvaoj10603


   1.这题果断用广度搜索(BFS),最重要的是控制加进去的元素条件,条件很重要,否则很容易无限循环一直累加,知道数组超界停止...

    2.深搜 最重要的是控制 递归的结束条件,还有尽可能使之不重复的列举。会控制终止条件,很关键。(否则  time limited exceed...)

    3.这题用C++也很方便,set容器(内放结构体,较好用),你只用添加,set会为你判断该状态是否重复了,set就是像集合一样,只含不同的元素。

--------------------------------------------------------------------------

  这个题的确很容易错!我想了两天了,为什么带了几十组数据,答案对了,却通不过,,,其实易错点就是取值total(它要求最小的情况,判断条件的设置很关键),我在这里是每一次状态就进行一次判断,判断两种情况

   1.找到过 d 了,以后就避开d' < d 判断的可能,以后就直接找 满足d时的最小total就可以啦

   2.在这次状态下,之前从来没有找到过d,顺便找找接近d的total最小值,我是在这里掉到坑里了。判断条件要心细!首先,先判断有没有值小于d的,找到后,在此基础上看res能不能更新,就是说res 这个记录d’的值能不能再大一些,那么就应该和该杯子中水的值进行比较。然后! 如果res和该水量一样,但可能加水过程是不一样的,还应该判断  rtotal是否能更新,去最小。

-------------------------------------------------------------------------

顺便提供一些常用测试数据,慢慢测吧...



INPUT             OUTPUT

137 148 199 1751213 170162 66 193 183426 163107 55 48 620 48144 29 70 1570 70196 46 5 1310 512 132 113 1710 11388 178 137 7488 4985 58 166 1107196 110102 199 182 142102 10238 41 65 1750 6546 121 96 8946 5074 166 149 1650 149101 47 188 1531445 153151 89 179 10189 901 17 67 930 67151 65 74 1065 98 30 64 3356 32170 22 71 1050 71108 192 142 1660 14222 158 158 68132 6625 99 6 1240 654 153 188 1611404 16142 34 169 5542 4252 169 98 200 043 36 199 1382279 13813 189 58 700 5845 120 181 176375 16640 43 56 1160 56198 42 118 38126 34138 29 194 1061480 106182 179 39 1630 3951 11 148 113695 113170 70 46 1240 4634 182 59 800 59133 78 80 4078 2172 172 97 1350 9798 147 14 150 14147 36 152 8252 8104 106 191 1910 19141 132 116 1160 116195 187 2 1390 254 29 170 38705 38138 186 83 270 0171 110 159 1790 159134 69 34 1490 34153 58 81 1850 81187 35 164 72140 70



--------------------------------------------------------------------------

不太会给变量起名字,没看懂的可以问哈
    



#include<stdio.h> #include<string.h> int volume[100000][4];  //volume[][3]就是每个状态的total(倒水总量),其实用                         //结构体比较简单明了,写完就后悔了int cup[4];          //cup[3]就是dint rtotal;int res,ok,minto;  //res 就是d’int visit[201][201];  //很巧妙,杯子的最大量度为200,则可能状态就是0到200,                       //共201种,又由于水是一定的量,那么有两个就可以确定整                      //个的状态,二维数组很方便又来标记void  bfs(  ){int front,rear,i,j,dv;front = rear =0;minto=1000000;int copy[4];volume[rear][0] = 0;volume[rear][1] = 0;volume[rear][2] = cup[2];volume[rear][3] = 0;rear++;while(front<rear){  copy[0]= volume[front][0];  copy[1]= volume[front][1];   copy[2]= volume[front][2];       copy[3]= volume[front][3]; if(copy[0]==cup[3] ||  copy[1]==cup[3] ||  copy[2]==cup[3]) { if( minto > copy[3]){minto = copy[3];ok = 1;} } else if(ok==0) { for(i=0;i<3;i++) { if(copy[i]<cup[3] ) { if(res < copy[i]) { res = copy[i];     rtotal = copy[3]; } else if(res == copy[i]) { if(rtotal>copy[3])rtotal = copy[3]; } } } }         front++; for(i=0;i<3;i++) {   if(copy[i]!=0)for(j=0;j<3 ;j++){if(j!=i && copy[j]<cup[j]){dv = cup[j]-copy[j]>copy[i]?copy[i]:cup[j]-copy[j];volume[rear][j] = copy[j] + dv;volume[rear][i]  = copy[i] - dv;                    volume[rear][3]  = copy[3] + dv;volume[rear][3-i-j] = copy[3-i-j];          if(visit[volume[rear][0]][volume[rear][1]]==0 && minto >= volume[rear][3]){visit[volume[rear][0]][volume[rear][1]]=1;rear++;}}} }      }}int main(){int n,i;scanf("%d",&n);    while(n--){memset(visit,0,sizeof(visit));for(i=0;i<4;i++){scanf("%d",&cup[i]);}         res = 0;ok=0;rtotal =0;bfs();if(ok)printf("%d %d\n",minto,cup[3]);else                printf("%d %d\n",rtotal,res);}return 0;}

0 0
原创粉丝点击