NOIP2016模拟赛 day6

转移阵地,我们继续(伤害)

---------------------------------------------(我是分割线)-------------------------------------------------

T1:city

  题目:给定一棵最小生成树(保证唯一),求其完全图的最小边权和

  数据规模:对于100%的数据,点数n≤20000

  思路:手动模拟一次,发现对于最后完全图的边分为两种情况,一种是于最小生成树内的,另外一种是新加的。对于所有新加的边,为了保证最小生成树的唯一,设从i->j经过的边长分别为a,b,c,那么显然可得,i到j之间的最小边长min(i,j)=max{a,b,c}+1,考虑最小生成树内的每一条边都会有对答案的贡献,那么将每一条边按权值由大到小排序后,每一条边对于答案的贡献即为(w+1)*siz[fx]*siz[fy]-1,之后将这条边擦去。以上操作均可以用并查集完成。

代码:

const
  maxn=40000;
type
  rec=record
        x,y,w:longint;
      end;
var
  a:array[1..maxn] of rec;
  f,siz:array[1..maxn] of longint;
  i,n,fx,fy:longint;
  ans:int64;
  procedure qsort(l,r:longint);
  var
    i,j:longint;
    mid,tmp:rec;
  begin
    i:=l; j:=r; mid:=a[(l+r) div 2];
    repeat
      while a[i].wmid.w do dec(j);
      if i<=j then
      begin
        tmp:=a[i];
        a[i]:=a[j];
        a[j]:=tmp;
        inc(i);
        dec(j);
      end;
    until i>j;
    if i

T2:coin

  题目:给定n种硬币,每种硬币的面值为ai,各有无限个。有T个询问,询问能否用给出的n种硬币凑出面值M,输出最小的硬币个数,否则输出-1

  数据规模:对于100%的数据,n≤100,1≤ai≤10^3,1≤M≤10^16,1≤T≤10^5

  思路:乍一看,怎么感觉都是背包问题,但是一看数据规模就知道没那么简单。换个角度思考,当M在没有到达一个一定的范围之前,无脑拿最大的肯定是最优的,那在进入到一定范围之后,选取最优值即可,而明显那一部分是我们可以预处理的,鉴于M的范围,选择背包预处理1~max(ai)^2,那么ans[M]=op+f[M-op*mx],op=(M-max(ai)^2-1) div mx+1

代码:

const
  inf=1684300900;
var
  a:array[1..2000] of longint;
  f:array[1..2000000] of longint;
  n,i,j,t:longint;
  m,ans,mx,op,tmp:int64;
  function max(a,b:longint):longint;
  begin
    if a>b then exit(a) else exit(b);
  end;
  function min(a,b:longint):longint;
  begin
    if a0 do
  begin
    readln(m);
    dec(t);
    if (m<=sqr(mx)) then
    begin
      if f[m]<>inf then writeln(f[m]) else writeln(-1);
      continue;
    end;
    op:=(m-sqr(mx)-1) div mx+1;
    if f[m-op*mx]=inf then writeln(-1) else writeln(f[m-op*mx]+op);
  end;
end.


T3:shugo(日常惨案,全部人都报0_(:зゝ∠)_,等后续施工吧)

  题目:SingleLyra是一名考古学家,有一天他发现了远古时期的一段文本,这段文本是一个严格上升的十进制数序列,然而现在所有数字连在了一起,因此SingleLyra只能得到一个十进制字符串。        SingleLyra想恢复出来这段文字,为了更加符合原始文本,需要将序列的最后一个数字尽可能小,在此基础上,要求这个序列的字典序尽量大。(字典序尽量大指的是,如果有相同的方案,要求第一个数最大,若第一个数相同,要求第二个数最大,以此类推)。  注意:恢复时允许前导0的出现。

  数据规模:对于 30% 的数据:1<=|S|<=2000; 对于 100% 的数据:1<=|S|<=100000

你可能感兴趣的:(NOIP2016模拟赛 day6)