HOJ 2608 Assemble(二分)
用一个结构体保存每一个部件,包括quality,price,name,type.
先按quality降序排序,注意排序的时候不要将同类的部件打散,要保证同一类部件连在一起。
再用componets数组,记录从i到j是哪一个部件。如componets[i]=0,componets[i+1]=3,则知第0到第2条记录是属于部件i的。
然后关于质量进行二分。质量的范围取所有部件的质量最大、最小值。
若在所有部件类型中,都能满足大于等于这个质量,并且花费不超过budget的,return true,然后调高mid,再进行判断。最后获得一个尽可能高的最低质量。
否则return false。调低mid。
总之,还是一道典型的二分。
但是总是在各种细节上处理不好,经常犯粗心大意的毛病,debug很久也找不到错误。。感觉很浪费时间。
AC代码如下:
#include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; struct element { int price,quality; char str1[21],str2[21]; }; element elem[1001]; int componets[1001]; int n,b; int dn=0; bool cmp(element a,element b) { if(strcmp(a.str1,b.str1)==0)return a.quality>b.quality; else return (strcmp(a.str1,b.str1)<0); } bool judge(int mid) { int i,j,tmin; int sum=0; for(i=0; i<dn; i++) { tmin=1000000001; for(j=componets[i]; j<componets[i+1]; j++) { if(mid<=elem[j].quality) tmin=(tmin<elem[j].price?tmin:elem[j].price); else break; } if(tmin!=1000000001)sum+=tmin; else return false; } if(sum>b)return false; else return true; } int main() { int t; int qmax=-1; int qmin=1000000001; cin>>t; while(t--) { int flag=0; cin>>n>>b; for(int i=0; i<n; i++) { scanf("%s%s%d%d",elem[i].str1,elem[i].str2,&elem[i].price,&elem[i].quality); qmax=(qmax>elem[i].quality?qmax:elem[i].quality); qmin=(qmin<elem[i].quality?qmin:elem[i].quality); } sort(elem,elem+n,cmp); memset(componets,0,sizeof(componets)); dn=0; for(int i=1; i<n; i++) { if(strcmp(elem[i].str1,elem[i-1].str1)!=0)componets[++dn]=i; } componets[++dn]=n; int mid,res; int high,low; high=qmax; low=qmin; while(low<=high) //对质量进行二分,尽可能取大的质量 { mid=(low+high)>>1; if(judge(mid)) { low=mid+1; res=mid; flag=1; } else high=mid-1; } if(flag) printf("%d\n",res); else printf("0\n"); } return 0; }