• JZOJ 4.22 2129——【2017.4.21普及】礼物


    题目描述

    圣诞节这天,某商店准备了N个礼品盒,分别用整数1-N进行编号。其中,编号为1的盒子中有一个糖果,编号为2的盒子中有2个糖果,。。。编号为N的盒子中有N个糖果。这天一早,中山幼儿园的K个小朋友一起来到这间商店。作为当天的第一批顾客,这些小朋友可以从这N个礼品盒中选出两个拿走。小朋友们商量了一会儿后决定,他们拿走的糖果并不一定要多,但是一定要能够刚好平分给每个人。即拿走的两个盒子中的糖果总数一定要使K的倍数。现在他们想知道一共有多少种方案可供选择。

    输入

    每行两个正整数N和K,其中1<=N<=10^9,1<=K<=10^9。一行N=K=0
    表示输入结束,这一行不用处理。

    输出

    对输入中除了N=K=0外的每一行,输出一行,这一行只有一个数,即其相对应的输入所得到的方案数。

    样例输入

    1 1
    3 2
    5 2
    50 50
    0 0

    样例输出

    0
    1
    4
    24

    数据范围限制

    20%的数据N<=100;
    80%的数据K<=1000;
    每个输入文件最多有200行输入数据。


    20%:
    直接暴力,o(n`2)枚举每一种情况

    代码如下:

    var  ans,i,j,x,y,l:longint;
         a:array[0..1000000]of longint;
    begin
      assign(input,'gift.in');
      assign(output,'gift.out');
      reset(input);
      rewrite(output);
      while not eoln() do
        begin
          ans:=0;
          l:=0;
          fillchar(a,sizeof(a),#0);
          readln(x,y);
          if (x=0)and(y=0) then begin close(input); close(output); halt; end;
          for i:=1 to x-1 do
            for j:=i+1 to x do
              if (i+j)mod y=0 then inc(ans);
          writeln(ans);
        end;
      close(input);
      close(output);
    end.
    

    40%:
    40分就要推出简易公式,枚举n个数可能可以拼成m的倍数——z。
    ①当(z>x)and(((x*2)-z) mod 2=0) max:=max+(x-(z-x)) div 2
    ②当(z>x)and(((x*2)-z) mod 2=1) max:=max+(x-(z-x)) div 2+1
    ③当(z<=x)and(z mod 2=0) max:=max+z div 2-1
    ④当(z<=x)and(z mod 2=1) max:=max+z div 2

    代码如下:

    var   max,x,y,z:int64;
           i:longint;
    begin
      assign(input,'gift.in');
      assign(output,'gift.out');
      reset(input);
      rewrite(output);
      while not eoln() do
        begin
          max:=0;
          readln(x,y);
          if (x=0)and(y=0) then begin close(input); close(output); halt; end;
          for i:=1 to x*2 div y do
            begin
              z:=i*y;
              if z>=x*2 then break;
              if z>x then
                if (x*2-z) mod 2=0 then max:=max+(x-(z-x)) div 2
                else max:=max+(x*2-z) div 2+1
              else if z mod 2<>0 then max:=max+z div 2 else max:=max+z div 2-1;
            end;
          writeln(max);
        end;
      close(input);
      close(output);
    end.

    100%:
    如果有x,y,a,b,x%k==a,y%k==b,a+b==k,则(x+y)%k==0。根据这个特性,我们可以列张表,然后利用乘法原理,一一配对。然而,可以直接被k整除的,要特殊判断;k为偶数时也要特判断。
    再分情况讨论:
    1、k为奇数且n%k没过k一半时
    2、k为奇数且n%k过k一半时
    3、k为偶数且n%k没过k一半时
    4、k为偶数且n%k过k一半时

    代码如下:

    var  n,m,x,y,z,x1:int64;
    begin
      assign(input,'gift.in');
      assign(output,'gift.out');
      reset(input);
      rewrite(output);
      readln(n,m);
      while (n<>0)and(m<>0) do
        begin
          x:=n div m;
          y:=n mod m;
          z:=(m-1) div 2;
          x1:=x*(x-1)div 2+x*x*z;
          if (m mod 2=0) then x1:=x1+x*(x-1)div 2; 
          if y>0 then
            begin
              if (y>=z) then x1:=x1+x*z else x1:=x1+x*y;
              y:=y-z;
              if (y>0)and(m mod 2=0)then
                begin
                  x1:=x1-x*(x-1)div 2+x*(x+1) div 2;
                  y:=y-1;
                end;
              if (y>0) then x1:=x1+(x+1)*y;
            end;
          writeln(x1);
          readln(n,m);
        end;
      close(input);
      close(output);
    end.

  • 相关阅读:
    Codeforces Round #397 (Div. 1 + Div. 2 combined) D. Artsem and Saunders 构造
    Codeforces Round #393 (Div. 2) D. Travel Card DP
    Codeforces Round #395 (Div. 2) D. Timofey and rectangles 思维题
    Codeforces Round #396 (Div. 2) E. Mahmoud and a xor trip 二进制拆位+树型dp
    Codeforces Round #396 (Div. 2) D. Mahmoud and a Dictionary 并查集
    Codeforces Round #395 (Div. 2) C. Timofey and a tree 树
    Codeforces Round #394 (Div. 2) E. Dasha and Puzzle DFS
    upper_bound & lower_bound
    【转】立方体的体对角线穿过多少个正方体?
    Codeforces Round #353 (Div. 2) D. Tree Construction 树
  • 原文地址:https://www.cnblogs.com/Comfortable/p/8412303.html
Copyright © 2020-2023  润新知