問題一覧 > スコア問題

No.2596 Christmas Eve (Heuristic ver.)

レベル : / 実行時間制限 : 1ケース 1.224秒 / メモリ制限 : 512 MB / スペシャルジャッジ問題 (複数の解が存在する可能性があります)
タグ : / 解いたユーザー数 13
作問者 : hirayuu_yc / テスター : rhoo
0 ProblemId : 10320 / 出題時の順位表 / 自分の提出
問題文最終更新日: 2023-12-23 20:14:43

注意

この問題はアドベコン用の問題です。

正当な出力をしてACすることができたら★1.5相当の点数が与えられます。

スコア問題としての順位は「スコア順」タブをご覧ください。

実行制限時間について

この問題の実行制限時間は 1224ms1224\text{ms} であることに注意してください。

比較的遅い言語でもACすることは可能ですが、より良いスコアを目指す場合は高速な言語を使うことをおすすめします。

問題文

NN 個の「木の先端」、2N2N 個の「木の中央」、NN 個の「木の幹」があります。以降、これらをまとめてパーツと呼びます。

  • ii 個目の「木の先端」は幅、高さがそれぞれ ai,bia_i,b_i です。
  • jj 個目の「木の中央」は幅、高さがそれぞれ cj,djc_j,d_j です。
  • kk 個目の「木の幹」は幅、高さがそれぞれ ek,fke_k,f_k です。

クリスマスツリーを 11 つ作るには、「木の先端」を 11 つ、「木の中央」を 22 つ、「木の幹」を 11 つ、以下の条件をすべて満たすように選ぶ必要があります。

  • 「木の幹」の幅は、選んだ他のパーツの幅よりも小さい
  • 「木の先端」の幅は、選んだどちらの「木の中央」の幅よりも小さい

クリスマスツリーの高さは、選んだパーツの高さの合計です。

はるく君は、パーツを組み合わせて KK 個のクリスマスツリーを作ろうとしています。ただし、複数のクリスマスツリーに同じパーツを使うことはできません。

はるく君は、作ったクリスマスツリーの高さができる限り近くなるようにしたいです。

より正確には、作ったクリスマスツリーの中で最も高いものの高さを HmaxH_{max} 、最も低いものの高さを HminH_{min} として、HmaxHminH_{max}-H_{min} をできる限り小さくしたいです。

はるく君のために、 HmaxHminH_{max}-H_{min} が小さいクリスマスツリーの作り方を教えてあげてください。

入力

N KN\ K
a1,a2,,aNa_1,a_2,\dots,a_N
b1,b2,,bNb_1,b_2,\dots,b_N
c1,c2,,c2Nc_1,c_2,\dots,c_{2N}
d1,d2,,d2Nd_1,d_2,\dots,d_{2N}
e1,e2,,eNe_1,e_2,\dots,e_N
f1,f2,,fNf_1,f_2,\dots,f_N
  • N=500N=500
  • 300K400300\leq K\leq 400
  • 1ai,bi,ci,di,ei,fi100001\leq a_i,b_i,c_i,d_i,e_i,f_i\leq 10000
  • 入力はすべて整数
  • 問題文中の条件を満たすように KK 個のクリスマスツリーを作れる

出力

KK 行出力してください。

ii 行目には、ii 番目のクリスマスツリーに uiu_i 番目の「木の先端」、viv_i 番目と wiw_i 番目の「木の中央」、xix_i 番目の「木の幹」を使うとき、以下のように出力してください。

ui vi wi xiu_i\ v_i\ w_i\ x_i

このとき、以下の条件をすべて満たす必要があります。

  • 1ui,xiN1\leq u_i,x_i\leq N
  • 1vi,wi2N1\leq v_i,w_i\leq 2N
  • uiuj,vivj,wiwj,xixj(ij)u_i\ne u_j,v_i\ne v_j,w_i\ne w_j,x_i\ne x_j(i\ne j)
  • viwjv_i\ne w_j
  • exi<auie_{x_i}< a_{u_i}
  • exi<cvie_{x_i}< c_{v_i}
  • exi<cwie_{x_i}< c_{w_i}
  • aui<cvia_{u_i}< c_{v_i}
  • aui<cwia_{u_i}< c_{w_i}

得点

出力が問題文の条件を満たしていない場合、WAと判定されます。そうでなく、プログラムが時間内に正常終了していればACと判定されます。

テストケースの得点は、 40000(HmaxHmin)40000-(H_{max}-H_{min}) です。

提出コードはのスコアは、125個のテストケースすべての得点の合計です。コンテスト後のシステムテストは行われません。

入力生成方法

この項目を読まなくても問題の理解に支障はありません。

平均 μμ 、標準偏差 σσ の正規分布にしたがって乱数を生成する関数を normal(μ,σ)\text{normal}(μ,σ)aa 以上 bb 以下の整数を一様ランダムに生成する関数を rand(a,b)\text{rand}(a,b) と表します。

  1. N=500,N=500, K=rand(300,400)K=\text{rand}(300,400) とします。

  2. 1iK,1j41\le i\le K,1\le j\le4 に対して
    wi,j=max(1,min(10000,normal(5000,1600)))w_{i,j}=\max(1,\min(10000,\lfloor \text{normal}(5000,1600) \rfloor)) とします。
    ただし、 wiw_i に同じ値が複数回出現するような ii が存在すれば wiw_i の各要素の生成はやり直され、それはこのような ii が存在しなくなるまで続けられます。

  3. ii について wiw_i の要素を昇順に並び替えます。

  4. 1iK1\le i\le K について

    • ai=wi,2a_i=w_{i,2}
    • ci=wi,3c_{i}=w_{i,3}
    • ci+N=wi,4c_{i+N}=w_{i,4}
    • ei=wi,1e_i=w_{i,1}
    とします。
  5. K+1iNK+1\le i\le N について

    • ai=max(1,min(10000,normal(5000,1600)))a_i=\max(1,\min(10000,\lfloor \text{normal}(5000,1600) \rfloor))
    • ci=max(1,min(10000,normal(5000,1600)))c_{i}=\max(1,\min(10000,\lfloor \text{normal}(5000,1600) \rfloor))
    • ci+N=max(1,min(10000,normal(5000,1600)))c_{i+N}=\max(1,\min(10000,\lfloor \text{normal}(5000,1600) \rfloor))
    • ei=max(1,min(10000,normal(5000,1600)))e_i=\max(1,\min(10000,\lfloor \text{normal}(5000,1600) \rfloor))
    とします。
  6. a,c,ea,c,e をランダムに並び替えます。

  7. 1iN1\le i\le N について

    • bi=max(1,min(1000,normal(ai,500)))b_i=\max(1,\min(1000,\lfloor \text{normal}(a_i,500)\rfloor))
    • di=max(1,min(1000,normal(di,500)))d_i=\max(1,\min(1000,\lfloor \text{normal}(d_i,500)\rfloor))
    • di+N=max(1,min(1000,normal(di+N,500)))d_{i+N}=\max(1,\min(1000,\lfloor \text{normal}(d_{i+N},500)\rfloor))
    • fi=max(1,min(1000,normal(fi,500)))f_i=\max(1,\min(1000,\lfloor \text{normal}(f_i,500)\rfloor))
    とします。
ジェネレータコード (Python)
import random

def high(wide):
    return max(1,min(10000,int(random.gauss(wide,500))))
N=500
K=random.randint(300,400)
a=[]
b=[]
c=[]
d=[]
e=[]
f=[]
for i in range(K):
    wide=[max(1,min(10000,int(random.gauss(5000,1600)))) for i in range(4)]
    while len(set(wide))!=4:
        wide=[max(1,min(10000,int(random.gauss(5000,1600)))) for i in range(4)]
    wide.sort()
    e.append(wide[0])
    c.append(wide[3])
    c.append(wide[2])
    a.append(wide[1])
for i in range(N-K):
    e.append(max(1,min(10000,int(random.gauss(5000,1600)))))
    c.append(max(1,min(10000,int(random.gauss(5000,1600)))))
    c.append(max(1,min(10000,int(random.gauss(5000,1600)))))
    a.append(max(1,min(10000,int(random.gauss(5000,1600)))))
random.shuffle(a)
random.shuffle(c)
random.shuffle(e)
for i in range(N):
    b.append(high(a[i]))
    f.append(high(e[i]))
    d.append(high(c[i*2]))
    d.append(high(c[i*2+1]))
print(N,K)
print(*a)
print(*b)
print(*c)
print(*d)
print(*e)
print(*f)

サンプル

サンプル1
入力
3 2
2 5 6
3 4 3
9 9 8 2 4 4
1 4 2 8 5 7
1 2 3
7 5 3
出力
1 2 5 1
2 3 1 2

この入力例は制約を満たしておらず、実際のテストケースとしては与えられません。

11 つ目のクリスマスツリーの高さは 3+4+5+7=193+4+5+7=1922 つ目のクリスマスツリーの高さは 4+2+1+5=124+2+1+5=12 なので、40000(1912)=3999340000-(19-12)=39993 点となります。

提出するには、Twitter 、GitHub、 Googleもしくは右上の雲マークをクリックしてアカウントを作成してください。