zoukankan      html  css  js  c++  java
  • 3140:[HNOI2013]消毒

    题目描述 Description
    最近在生物实验室工作的小 T 遇到了大麻烦。
    由于实验室最近升级的缘故,他的分格实验皿是一个长方体,其尺寸为 a*b*c,a、b、c均为正整数。为了实验的方便,它被划分为 a*b*c 个单位立方体区域,每个单位立方体尺寸为 1*1*1。用(i,j,k)标识一个单位立方体,1≤i≤a,1≤j≤b,1≤k≤c。这个实验皿已经很久没有人用了,现在,小 T 被导师要求将其中一些单位立方体区域进行消毒操作(每个区域可以被重复消毒)。而由于严格的实验要求,他被要求使用一种特定的 F 试剂来进行消毒。
    这种 F 试剂特别奇怪,每次对尺寸为 x*y*z 的长方体区域(它由 x*y*z 个单位立方体组成)进行消毒时,只需要使用 min{x,y,z}单位的 F 试剂。F 试剂的价格不菲,这可难倒了小T。现在请你告诉他,最少要用多少单位的 F 试剂。(注:min{x,y,z}表示 x、y、z 中的最小者。)

    输入描述 Input Description
    输入文件第一行是一个正整数D,表示数据组数。
    接下来是D组数据,每组数据开头是三个数a,b,c表示实验皿的尺寸。接下来会出现a个b行c列的用空格隔开的01矩阵,0表示对应的单位立方体不要求消毒,1表示对应的单位立方体需要消毒;例如,如果第1个01矩阵的第2行第3列为1,则表示单位立方体(1,2,3)需要被消毒。
    输入保证满足a*b*c≤5000,T≤3。
    输出描述 Output Description
    仅包含 D 行,每行一个整数,表示对应实验皿最少要用多少单位的 F 试剂。
    样例输入 Sample Input
    1
    4 4 4
    1 0 1 1
    0 0 1 1
    0 0 0 0
    0 0 0 0
    0 0 1 1
    1 0 1 1
    0 0 0 0
    0 0 0 0
    0 0 0 0
    0 0 0 0
    1 0 0 0
    0 0 0 0
    0 0 0 0
    0 0 0 0
    0 0 0 0
    1 0 0 0
    样例输出 Sample Output
    3
    数据范围及提示 Data Size & Hint
    对于区域(1,1,3)-(2,2,4)和(1,1,1)-(4,4,1)消毒,分别花费2个单位和1个单位的F试剂。

    终于过了,fillchar没有一点优势啊
    还是用各种for来把赋初值快一些


    二维的怎么做大家都知道,就是二分图匹配,但是这是三维
    怎么办呢?
    !!!!强行转化成二维,枚举第三维的情况,那这需要2^k所以我们找最小的k
    因为a*b*c<=5000,所以min{a,b,c}最大是17左右
    然后开始枚举,但是还是很吃力所以对于把一个数组重新赋值的事最好避免

      1 var
      2     f:array[0..5000,1..3]of longint;
      3     first,next,last,cover,bool:array[0..5000]of longint;
      4     flag,sum:array[0..20]of boolean;
      5     a,b,c,tot,num,min,aug,ans,match,t,time,time2,maxa,maxb,maxc:longint;
      6 
      7 procedure swap(var x,y:longint);
      8 var
      9     t:longint;
     10 begin
     11     t:=x;
     12     x:=y;
     13     y:=t;
     14 end;
     15 
     16 procedure init;
     17 var
     18     i,j,k,s,ai,bi,ci:longint;
     19 begin
     20     read(ai,bi,ci);
     21     a:=1;
     22     b:=2;
     23     c:=3;
     24     num:=0;
     25     maxa:=0;
     26     maxb:=0;
     27     maxc:=0;
     28     for i:=1 to ai do
     29       for j:=1 to bi do
     30         for k:=1 to ci do
     31           begin
     32             read(s);
     33             if s=1 then
     34             begin
     35               inc(num);
     36               f[num,1]:=i;
     37               f[num,2]:=j;
     38               f[num,3]:=k;
     39               if i>maxa then maxa:=i;
     40               if j>maxb then maxb:=j;
     41               if k>maxc then maxc:=k;
     42             end;
     43           end;
     44     min:=ai;
     45     if bi<min then min:=bi;
     46     if ci<min then min:=ci;
     47     if (bi<=ai)and(bi<=ci) then
     48       begin
     49         swap(a,b);
     50         swap(maxa,maxb);
     51       end
     52     else
     53       if (ci<=ai)and(ci<=bi) then
     54       begin
     55         swap(a,c);
     56         swap(maxa,maxc);
     57       end;
     58     fillchar(sum,sizeof(sum),false);
     59     for i:=1 to num do
     60       sum[f[i,a]]:=true;
     61 end;
     62 
     63 function path(x:integer):boolean;
     64 var
     65     i:integer;
     66 begin
     67     i:=first[x];
     68     while i<>0 do
     69       begin
     70         if bool[last[i]]<>time2 then
     71           begin
     72             bool[last[i]]:=time2;
     73             if (cover[last[i]]=0)or(path(cover[last[i]])) then
     74             begin
     75               cover[last[i]]:=x;
     76               exit(true);
     77             end;
     78           end;
     79         i:=next[i];
     80       end;
     81     exit(false);
     82 end;
     83 
     84 procedure insert(x,y:integer);
     85 begin
     86     inc(tot);
     87     last[tot]:=y;
     88     next[tot]:=first[x];
     89     first[x]:=tot;
     90 end;
     91 
     92 procedure work;
     93 var
     94     i:integer;
     95 begin
     96     if aug>ans then exit;
     97     tot:=0;
     98     match:=0;
     99     for i:=1 to maxb do
    100       first[i]:=0;
    101     for i:=1 to maxc do
    102       cover[i]:=0;
    103     for i:=1 to num do
    104       if flag[f[i,a]] then insert(f[i,b],f[i,c]);
    105     for i:=1 to maxb do
    106       begin
    107         inc(time2);
    108         if path(i) then inc(match);
    109       end;
    110     if ans>aug+match then ans:=aug+match;
    111 end;
    112 
    113 procedure try(x:integer);
    114 begin
    115     if x>min then work
    116     else
    117       begin
    118         flag[x]:=true;
    119         try(x+1);
    120         if sum[x] then
    121         begin
    122           flag[x]:=false;
    123           inc(aug);
    124           try(x+1);
    125           dec(aug);
    126         end;
    127       end;
    128 end;
    129 
    130 begin
    131     read(t);
    132     for time:=1 to t do
    133       begin
    134         init;
    135         ans:=200;
    136         try(1);
    137         writeln(ans);
    138       end;
    139 end.
    View Code
  • 相关阅读:
    结对编程作业
    软件工程网络15个人阅读作业1
    Java课程设计——学生基本信息管理
    JAVA课程设计
    201521123102 《Java程序设计》第12周学习总结
    201521123102 《Java程序设计》第11周学习总结
    201521123102 《Java程序设计》第9周学习总结
    个人作业5——软工个人总结
    alpha阶段个人总结
    案例分析
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3582404.html
Copyright © 2011-2022 走看看