解题报告 买花

1.        题目

 

买花Flower

【问题描述】

又到了一年一度的七夕节,逢此佳节,小T当然是要浪漫一下,去给小L买花。(虽然……TAT),今年,小T由于经费充足,因此他制定了一个特别的买花计划:买M束花,使得任意两束花的支数都不同,并且,尽管经费充足,也不能乱挥霍,因此小T决定对于这M束花,编号为1到M,第i束花恰好有i支花

然而,计划总是赶不上变化。直到七夕前一天,小T才得知,小L最讨厌和M互质的数字,因此,小L会扔掉所有支数与M互质的花束。小T非常伤心,但是由于智商有限,小T只会按照原定计划进行。现在,小T的经费一共支持按照计划最多买N束花,但是,小T也可以选择买少于N束花。假如小T买了M束花,那么,第i束花仍然恰好有i支。

现在,小T希望聪明的你帮他制定一个最好的方案,使得被小L扔掉花束的比例尽可能小。

PS:看不懂题面的可以看这个:

即求一个小于等于M的数N,使得phi(N)/N最小,其中phi(N)是与N互质的数的个数。

例如phi(4)=2,因为1,3和4互质。

 

【输入格式】

一行一个正整数M。

 

【输出格式】

一行一个正整数N。

 

【样例输入】

10

 

【样例输出】

6

 

 

数据范围:

对于30%的数据,N<=1000

对于60%的数据,N<=1000,000,000

对于100%的数据,N<=10^40

 

2.        算法

暴搜后发现,由连续的质数相乘所得的,比 m 小的最大的数,就是 n 。

3.        注意事项

要用到高精乘和高精比较。

4.        代码

水高精(SueMiller)

type arr=array[0..200]of longint;

 

var v:array[0..10000]of boolean;

    i,j,k:longint;

    a:array[0..10000]of longint;

    ns:string;

    n,temp:arr;

    nn,code,tt:longint;

 

function bj(temp,n:arr):boolean;

var i:integer;

begin

  if temp[0]>n[0] then exit(true);

  if temp[0]<n[0] then exit(false);

 

  for i:=n[0] downto 1 do

    begin

      if temp[i]>n[i] then exit(true);

      if n[i]>temp[i] then exit(false);

    end;

end;

 

function mul(temp:arr;x:longint):arr;

var i:integer;

begin

 

  for i:=1 to temp[0] do

    begin

      temp[i]:=temp[i]*x;

    end;

 

  for i:=1 to temp[0] do

    begin

      while temp[i]>=10 do

        begin

          temp[i+1]:=temp[i+1]+temp[i] div 10;

          temp[i]:=temp[i] mod 10;

        end;

    end;

 

  while temp[temp[0]+1]>0 do

    begin

      inc(temp[0]);

      temp[temp[0]+1]:=temp[temp[0]] div 10;

      temp[temp[0]]:=temp[temp[0]] mod 10;

    end;

 

  exit(temp);

end;

 

begin

  assign(input,'flower.in');reset(input);

  assign(output,'flower.out');rewrite(output);

 

  fillchar(v,sizeof(v),false);

  for i:=2 to 10000 do

    if not v[i] then

      begin

        j:=i;

        while j+i<=10000 do

          begin

            j:=j+i;

            v[j]:=true;

          end;

      end;

 

  k:=0;

  for i:=2 to 10000 do

    if not v[i] then

      begin

        inc(k);

        a[k]:=i;

      end;

 

 

  readln(ns);

  fillchar(n,sizeof(n),0);

  fillchar(temp,sizeof(temp),0);

  n[0]:=length(ns);

 

  for i:=n[0] downto 1 do

    begin

      n[n[0]-i+1]:=ord(ns[i])-48;

    end;

 

  temp[1]:=1;

  temp[0]:=1;

  i:=1;

 

  while not bj(mul(temp,a[i]),n) do

    begin

      temp:=mul(temp,a[i]);

      inc(i);

    end;

 

  for i:=temp[0] downto 1 do

    write(temp[i]);

  writeln;

 

  close(input);close(output);

end.

 

原文地址:https://www.cnblogs.com/SueMiller/p/2213420.html