JustinTX commited on
Commit
14c9c2b
·
verified ·
1 Parent(s): 1fd0050

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .claude/skills/dataclaw/SKILL.md +103 -0
  2. docker_space/frontier_cs_0_polyomino/0/.claude/settings.local.json +8 -0
  3. docker_space/frontier_cs_0_polyomino/0/INSTRUCTION.md +89 -0
  4. docker_space/frontier_cs_0_polyomino/0/best/evolution.log +24 -0
  5. docker_space/frontier_cs_0_polyomino/0/best/score.txt +12 -0
  6. docker_space/frontier_cs_0_polyomino/0/best/solution.cpp +337 -0
  7. docker_space/frontier_cs_0_polyomino/0/chk.cc +152 -0
  8. docker_space/frontier_cs_0_polyomino/0/config.yaml +12 -0
  9. docker_space/frontier_cs_0_polyomino/0/evaluate.md +76 -0
  10. docker_space/frontier_cs_0_polyomino/0/examples/gpt5.cpp +271 -0
  11. docker_space/frontier_cs_0_polyomino/0/examples/reference.cpp +297 -0
  12. docker_space/frontier_cs_0_polyomino/0/statement.txt +107 -0
  13. docker_space/frontier_cs_0_polyomino_ev2/.claude/settings.local.json +8 -0
  14. docker_space/frontier_cs_0_polyomino_ev2/best/best.cpp +535 -0
  15. docker_space/frontier_cs_0_polyomino_ev2/best/scores.txt +14 -0
  16. docker_space/frontier_cs_0_polyomino_ev2/examples/gpt5.cpp +271 -0
  17. docker_space/frontier_cs_0_polyomino_ev2/examples/reference.cpp +297 -0
  18. docker_space/frontier_cs_0_polyomino_ev2/logs/evolution.log +48 -0
  19. docker_space/frontier_cs_0_polyomino_ev2/logs/gen_0.cpp +297 -0
  20. docker_space/frontier_cs_0_polyomino_ev2/logs/gen_1.cpp +366 -0
  21. docker_space/frontier_cs_0_polyomino_ev2/logs/gen_18.cpp +515 -0
  22. docker_space/frontier_cs_0_polyomino_ev2/logs/gen_20.cpp +515 -0
  23. docker_space/frontier_cs_0_polyomino_ev2/logs/gen_26.cpp +516 -0
  24. docker_space/frontier_cs_0_polyomino_ev2/logs/gen_27.cpp +517 -0
  25. docker_space/frontier_cs_0_polyomino_ev2/logs/gen_28.cpp +517 -0
  26. docker_space/frontier_cs_0_polyomino_ev2/logs/gen_3.cpp +395 -0
  27. docker_space/frontier_cs_0_polyomino_ev2/logs/gen_30.cpp +517 -0
  28. docker_space/frontier_cs_0_polyomino_ev2/logs/gen_33.cpp +535 -0
  29. docker_space/frontier_cs_0_polyomino_ev2/logs/gen_5.cpp +399 -0
  30. docker_space/frontier_cs_1/examples/deepseekreasoner.cpp +232 -0
  31. docker_space/frontier_cs_1/examples/deepseekreasoner_1.cpp +174 -0
  32. docker_space/frontier_cs_1/examples/deepseekreasoner_2.cpp +265 -0
  33. docker_space/frontier_cs_1/examples/deepseekreasoner_3.cpp +179 -0
  34. docker_space/frontier_cs_1/examples/deepseekreasoner_4.cpp +300 -0
  35. docker_space/frontier_cs_1/examples/gemini2.5pro.cpp +234 -0
  36. docker_space/frontier_cs_1/examples/gemini2.5pro_2.cpp +185 -0
  37. docker_space/frontier_cs_1/examples/gemini2.5pro_3.cpp +184 -0
  38. docker_space/frontier_cs_1/examples/gemini2.5pro_4.cpp +203 -0
  39. docker_space/frontier_cs_1/examples/gemini3pro.cpp +217 -0
  40. docker_space/frontier_cs_1/examples/gemini3pro_1.cpp +287 -0
  41. docker_space/frontier_cs_1/examples/gemini3pro_2.cpp +288 -0
  42. docker_space/frontier_cs_1/examples/gemini3pro_3.cpp +251 -0
  43. docker_space/frontier_cs_1/examples/gemini3pro_4.cpp +284 -0
  44. docker_space/frontier_cs_1/examples/gpt5.1.cpp +334 -0
  45. docker_space/frontier_cs_1/examples/gpt5.1_1.cpp +304 -0
  46. docker_space/frontier_cs_1/examples/gpt5.1_2.cpp +302 -0
  47. docker_space/frontier_cs_1/examples/gpt5.1_3.cpp +353 -0
  48. docker_space/frontier_cs_1/examples/gpt5.1_4.cpp +308 -0
  49. docker_space/frontier_cs_1/examples/gpt5.2.cpp +546 -0
  50. docker_space/frontier_cs_1/examples/gpt5.2_1.cpp +437 -0
.claude/skills/dataclaw/SKILL.md ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: dataclaw
3
+ description: >
4
+ Export Claude Code, Codex, Gemini CLI, OpenCode, and OpenClaw conversation history to Hugging Face.
5
+ Use when the user asks about exporting conversations, uploading to Hugging Face,
6
+ configuring DataClaw, reviewing PII/secrets in exports, or managing their dataset.
7
+ allowed-tools: Bash(dataclaw *), Bash(huggingface-cli login *), Bash(pip install dataclaw*), Bash(grep *)
8
+ ---
9
+
10
+ <!-- dataclaw-begin -->
11
+
12
+ # DataClaw Skill
13
+
14
+ ## THE RULE
15
+
16
+ **Every `dataclaw` command outputs `next_steps`. FOLLOW THEM.**
17
+
18
+ Do not memorize the flow. Do not skip steps. Do not improvise.
19
+ Run the command → read the output → follow `next_steps`. That's it.
20
+
21
+ The CLI tracks your stage (1-4: auth → configure → review → done).
22
+ `dataclaw export` (push) is **gated** — you must run `dataclaw confirm` first or it will refuse.
23
+
24
+ ## Getting Started
25
+
26
+ Run `dataclaw status` (or `dataclaw prep` for full details) and follow the `next_steps`.
27
+
28
+ ## Output Format
29
+
30
+ - `dataclaw prep`, `dataclaw config`, `dataclaw status`, and `dataclaw confirm` output pure JSON
31
+ - `dataclaw export` outputs human-readable text followed by `---DATACLAW_JSON---` and a JSON block
32
+ - Always parse the JSON and act on `next_steps`
33
+
34
+ Key fields:
35
+ - `stage` / `stage_number` / `total_stages` — where you are
36
+ - `next_steps` — follow these in order
37
+ - `next_command` — the single most important command to run next (null if user input needed first)
38
+
39
+ ## PII Audit (Stage 3)
40
+
41
+ After `dataclaw export --no-push`, follow the `next_steps` in the JSON output. The flow is:
42
+
43
+ 1. **Ask the user their full name** — then grep the export for it
44
+ 2. **Run the pii_commands** from the JSON output and review results with the user
45
+ 3. **Ask the user what else to look for** — company names, client names, private URLs, other people's names, custom domains
46
+ 4. **Deep manual scan** — sample ~20 sessions (beginning, middle, end) and look for anything sensitive the regex missed
47
+ 5. **Fix and re-export** if anything found: `dataclaw config --redact "string"` then `dataclaw export --no-push`
48
+ 6. **Run `dataclaw confirm` with text attestations** — pass `--full-name`, `--attest-full-name`, `--attest-sensitive`, and `--attest-manual-scan`. It runs PII scan, verifies attestations, shows project breakdown, and unlocks pushing.
49
+ 7. **Push only after explicit user confirmation**: `dataclaw export --publish-attestation "User explicitly approved publishing to Hugging Face."`
50
+
51
+ ## Commands Reference
52
+
53
+ ```bash
54
+ dataclaw status # Show current stage and next steps (JSON)
55
+ dataclaw prep # Discover projects, check HF auth (JSON)
56
+ dataclaw prep --source all # All sources (Claude + Codex + Gemini + OpenCode + OpenClaw)
57
+ dataclaw prep --source claude # Only Claude Code sessions
58
+ dataclaw prep --source codex # Only Codex sessions
59
+ dataclaw prep --source gemini # Only Gemini CLI sessions
60
+ dataclaw prep --source opencode # Only OpenCode sessions
61
+ dataclaw prep --source openclaw # Only OpenClaw sessions
62
+ dataclaw confirm --full-name "NAME" --attest-full-name "..." --attest-sensitive "..." --attest-manual-scan "..." # Scan PII, verify attestations, unlock pushing (JSON)
63
+ dataclaw confirm --file /path/to/file.jsonl --full-name "NAME" --attest-full-name "..." --attest-sensitive "..." --attest-manual-scan "..." # Confirm a specific export file
64
+ dataclaw list # List all projects with exclusion status
65
+ dataclaw list --source all # List all sources
66
+ dataclaw list --source codex # List only Codex projects
67
+ dataclaw config # Show current config
68
+ dataclaw config --repo user/my-dataset # Set HF repo
69
+ dataclaw config --source all # REQUIRED source scope: claude|codex|gemini|opencode|openclaw|all
70
+ dataclaw config --exclude "a,b" # Add excluded projects (appends)
71
+ dataclaw config --redact "str1,str2" # Add strings to redact (appends)
72
+ dataclaw config --redact-usernames "u1,u2" # Add usernames to anonymize (appends)
73
+ dataclaw config --confirm-projects # Mark project selection as confirmed
74
+ dataclaw export --publish-attestation "..." # Export and push (requires dataclaw confirm first)
75
+ dataclaw export --no-push # Export locally only
76
+ dataclaw export --source all --no-push # Export all sources locally
77
+ dataclaw export --source codex --no-push # Export only Codex sessions
78
+ dataclaw export --source claude --no-push # Export only Claude Code sessions
79
+ dataclaw export --source gemini --no-push # Export only Gemini CLI sessions
80
+ dataclaw export --source opencode --no-push # Export only OpenCode sessions
81
+ dataclaw export --source openclaw --no-push # Export only OpenClaw sessions
82
+ dataclaw export --all-projects # Include everything (ignore exclusions)
83
+ dataclaw export --no-thinking # Exclude extended thinking blocks
84
+ dataclaw export -o /path/to/file.jsonl # Custom output path
85
+ dataclaw update-skill claude # Install/update the dataclaw skill for Claude Code
86
+ ```
87
+
88
+ ## Gotchas
89
+
90
+ - **Never run bare `huggingface-cli login`** — it's interactive and will hang. Always use `--token`.
91
+ - **`--exclude`, `--redact`, `--redact-usernames` APPEND** — they never overwrite. Safe to call repeatedly.
92
+ - **Source selection is REQUIRED before export** — explicitly set `dataclaw config --source claude|codex|gemini|opencode|openclaw|all` (or pass `--source ...` on export).
93
+ - **`dataclaw prep` outputs pure JSON** — parse it directly.
94
+ - **Always export with `--no-push` first** — review before publishing.
95
+ - **`dataclaw export` (push) requires `dataclaw confirm` first** — it will refuse otherwise. Re-exporting with `--no-push` resets this.
96
+ - **PII audit is critical** — automated redaction is not foolproof.
97
+ - **Large exports take time** — 500+ sessions may take 1-3 minutes. Use a generous timeout.
98
+
99
+ ## Prerequisite
100
+
101
+ `command -v dataclaw >/dev/null 2>&1 && echo "dataclaw: installed" || echo "NOT INSTALLED — run: pip install dataclaw"`
102
+
103
+ <!-- dataclaw-end -->
docker_space/frontier_cs_0_polyomino/0/.claude/settings.local.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "permissions": {
3
+ "deny": [
4
+ "WebFetch",
5
+ "WebSearch"
6
+ ]
7
+ }
8
+ }
docker_space/frontier_cs_0_polyomino/0/INSTRUCTION.md ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Polyomino Packing — Evolutionary Optimization Agent
2
+
3
+ You are an autonomous optimization agent. Your goal is to iteratively evolve a C++ solution for the Polyomino Packing problem to achieve the highest possible score.
4
+
5
+ ## Problem
6
+
7
+ Read `statement.txt` for the full problem description. In short: pack n polyominoes (each 1-10 cells) into a W×H rectangle with no overlaps, minimizing area. Score = 1e5 * Σk_i / (W*H), higher is better. There are 70 test cases with n ranging from 100 to 10000.
8
+
9
+ ## Evaluation
10
+
11
+ See `evaluate.md` for the full API reference. Quick summary:
12
+
13
+ ```bash
14
+ # Submit
15
+ SID=$(curl -s -X POST http://Competitive-Programming:8081/submit \
16
+ -F "code=@/workspace/solution.cpp" -F "pid=0" -F "lang=cpp" \
17
+ | python3 -c "import sys,json; print(json.load(sys.stdin)['sid'])")
18
+
19
+ # Poll (repeat until status is "done" or "error")
20
+ curl -s http://Competitive-Programming:8081/result/$SID
21
+ ```
22
+
23
+ - Time limit: 2s per test case, Memory limit: 256MB
24
+ - Solution must be a single self-contained C++ file
25
+
26
+ ## Your Workflow
27
+
28
+ Follow this evolutionary loop:
29
+
30
+ ### 1. Initialize
31
+ - Start from `examples/reference.cpp` as the baseline solution
32
+ - Copy it to `/workspace/solution.cpp`
33
+ - Evaluate it to get the baseline score
34
+ - Record it in the log
35
+
36
+ ### 2. Evolve (repeat for many generations)
37
+
38
+ For each generation:
39
+
40
+ 1. **Analyze** the current best solution — understand its algorithm, identify bottlenecks and weaknesses
41
+ 2. **Mutate** — apply ONE meaningful improvement. Ideas include:
42
+ - Better packing heuristics (bottom-left, skyline, shelf, guillotine)
43
+ - Smarter piece ordering (sort by area, by shape complexity, by bounding box)
44
+ - Better rotation/reflection selection per piece
45
+ - Local search / simulated annealing to improve placement
46
+ - Tighter bounding box estimation
47
+ - Better data structures for collision detection
48
+ - Time-aware optimization (use remaining time budget for local search)
49
+ 3. **Write** the mutated solution to `/workspace/solution.cpp`
50
+ 4. **Evaluate** — submit to judge and get the score
51
+ 5. **Select**:
52
+ - If score improved → keep the new solution as the current best
53
+ - If score decreased or errored → revert to the previous best
54
+ 6. **Log** the result (see below)
55
+
56
+ ### 3. Exploration vs Exploitation
57
+ - Don't just make small tweaks. Periodically try bold algorithmic changes
58
+ - If stuck at a plateau for 3+ generations, try a fundamentally different approach
59
+ - Consider maintaining 2-3 alternative solution strategies and switching between them
60
+ - Learn from failed attempts — record what didn't work and why
61
+
62
+ ## Logging
63
+
64
+ Create `/workspace/logs/` directory. For each generation, append to `/workspace/logs/evolution.log`:
65
+
66
+ ```
67
+ Gen <N> | Score: <score> | Best: <best_score> | Status: <improved/reverted/error> | Change: <brief description>
68
+ ```
69
+
70
+ Also save each generation's solution:
71
+ ```
72
+ /workspace/logs/gen_<N>.cpp
73
+ ```
74
+
75
+ Save the current best solution at `/workspace/best.cpp` at all times.
76
+
77
+ ## Important Rules
78
+
79
+ 1. **Never read testdata/** — solve the problem algorithmically, do not hardcode answers
80
+ 2. **Always keep a backup** of the current best before mutating
81
+ 3. **The solution must compile and run correctly** — syntax errors waste a generation
82
+ 4. **Stay within time/memory limits** — 2s per test, 256MB memory
83
+ 5. **Each solution must be a single .cpp file** — no external dependencies beyond standard library
84
+ 6. **Aim for at least 50 generations** — keep going as long as you're making progress
85
+ 7. **Be systematic** — don't repeat failed approaches, learn from each generation
86
+
87
+ ## Getting Started
88
+
89
+ Begin now. Initialize from the reference solution, evaluate it, then start evolving.
docker_space/frontier_cs_0_polyomino/0/best/evolution.log ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Gen 0 | Score: 86.46 | Best: 86.46 | Status: baseline | Change: reference.cpp (rectangular, all WA due to W!=H)
2
+ Gen 1 | Score: 60.92 | Best: 86.46 | Status: reverted | Change: square packing attempt, too slow (TLE)
3
+ Gen 2 | Score: 77.77 | Best: 77.77 | Status: improved | Change: x-step optimization, 4 TLE
4
+ Gen 3 | Score: 71.83 | Best: 77.77 | Status: reverted | Change: binary search approach, worse quality
5
+ Gen 4 | Score: 81.90 | Best: 81.90 | Status: improved | Change: better time mgmt, xMaxPos by size
6
+ Gen 5 | Score: 83.72 | Best: 83.72 | Status: improved | Change: xMaxPos=200, strict per-call budget, 0 TLE
7
+ Gen 6 | Score: 82.31 | Best: 83.72 | Status: reverted | Change: multi-ordering+sqMode, 1 TLE
8
+ Gen 7 | Score: 81.86 | Best: 83.72 | Status: reverted | Change: xMaxPos=50 for more dynLIM, worse quality
9
+ Gen 8 | Score: 83.10 | Best: 83.72 | Status: reverted | Change: adaptive W2, 1 TLE (case 3)
10
+ Gen 9 | Score: 83.08 | Best: 83.72 | Status: reverted | Change: tighter time mgmt, still 1 TLE
11
+ Gen 10 | Score: 79.70 | Best: 83.72 | Status: reverted | Change: S>5000 threshold, 4 TLE
12
+ Gen 11 | Score: 83.66 | Best: 83.72 | Status: reverted | Change: gen5+W2 post-opt, close but no gain
13
+ Gen 12 | Score: 82.78 | Best: 83.72 | Status: reverted | Change: hybrid S>15000, 1 TLE (case 3)
14
+ Gen 13 | Score: 83.72 | Best: 83.72 | Status: improved | Change: fix big threshold S>3000, hybrid S>15000 adaptive, 0 TLE
15
+ Gen 14 | Score: 84.20 | Best: 84.20 | Status: improved | Change: lower large threshold to S>10000, more cases get adaptive W2
16
+ Gen 15 | Score: 84.34 | Best: 84.34 | Status: improved | Change: lower threshold to S>7000
17
+ Gen 16 | Score: 84.89 | Best: 84.89 | Status: improved | Change: lower threshold to S>5000, case 3 huge improvement
18
+ Gen 21 | Score: 88.81 | Best: 88.81 | Status: improved | Change: reference solution with TL=1880, TLms=1800, big=S>3000. Rectangular packing (no W=H)
19
+ Gen 22 | Score: 89.02 | Best: 89.02 | Status: improved | Change: wider span, adaptive W2 post-opt
20
+ Gen 23 | Score: 88.99 | Best: 89.02 | Status: reverted | Change: W3 pass hurt 5 cases
21
+ Gen 24 | Score: 89.10 | Best: 89.10 | Status: improved | Change: random tie-breaking trials at best width
22
+ Gen 25 | Score: 89.21 | Best: 89.21 | Status: improved | Change: multi-width random trials
23
+ Gen 26 | Score: 89.11 | Best: 89.21 | Status: reverted | Change: wider trial range hurt
24
+ Gen 27 | Score: 88.84-89.12 (3 runs) | Best: ~89.0 | Status: improved stability | Change: TL=1800, TLms=1700, trial check avg*2.0. 0 TLE across 3 runs
docker_space/frontier_cs_0_polyomino/0/best/score.txt ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Best Score: 89.21 (Gen 25 peak)
2
+ Stable Score: 88.84 - 89.12 (Gen 27, 0 TLE across 3 runs)
3
+
4
+ Current best.cpp: Gen 27 (stable version)
5
+ - TL=1800ms, TLms=1700ms, big threshold S>3000
6
+ - Rectangular packing (W*H minimization, no W=H constraint)
7
+ - Adaptive W2 post-optimization
8
+ - Random tie-breaking trials at multiple widths
9
+
10
+ Key metrics (Gen 27 average):
11
+ - 70 test cases, 0 TLE
12
+ - Min ratio: ~0.85, Max ratio: ~0.94, Avg ratio: ~0.89
docker_space/frontier_cs_0_polyomino/0/best/solution.cpp ADDED
@@ -0,0 +1,337 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ SOURCE: Shang Zhou
3
+ IIMOC SUBMISSION #1443
4
+ HUMAN BEST FOR POLYPACK (TRANSFORMATION OUTPUT FORMAT)
5
+ */
6
+
7
+ #include <bits/stdc++.h>
8
+ using namespace std;
9
+ struct T{int w,h;vector<pair<int,int>> c;vector<int> lo,hi;int r,f,minx,miny;};
10
+ struct P{int id,k;vector<pair<int,int>> b;vector<T> t;int minW=1e9,minH=1e9,minA=1e9;};
11
+ struct Pl{int idx,ti,x,y;};
12
+ struct R{long long A;int W,H;vector<Pl> pl;};
13
+ struct RNG{unsigned long long s;RNG(unsigned long long x){s=x?x:1;}inline unsigned long long nxt(){s^=s<<7;s^=s>>9;return s;}inline int rint(int n){return (int)(nxt()%n);}inline bool coin(){return nxt()&1;}};
14
+ static inline pair<int,int> rotp(pair<int,int> p,int r){if(r==0)return p; if(r==1)return make_pair(-p.second,p.first); if(r==2)return make_pair(-p.first,-p.second); return make_pair(p.second,-p.first);}
15
+ int main(){
16
+ ios::sync_with_stdio(false);
17
+ cin.tie(nullptr);
18
+ int n; if(!(cin>>n)) return 0;
19
+ vector<P> ps(n); long long S=0;
20
+ for(int i=0;i<n;i++){
21
+ int k;cin>>k; ps[i].id=i+1; ps[i].k=k; ps[i].b.resize(k);
22
+ for(int j=0;j<k;j++){int x,y;cin>>x>>y; ps[i].b[j]={x,y};}
23
+ S+=k;
24
+ }
25
+ for(int i=0;i<n;i++){
26
+ auto &p=ps[i]; unordered_set<string> seen; seen.reserve(32);
27
+ for(int rf=0;rf<2;rf++){
28
+ vector<pair<int,int>> src=p.b; if(rf){for(auto &q:src) q.first=-q.first;}
29
+ for(int r=0;r<4;r++){
30
+ vector<pair<int,int>> v=src; for(auto &q:v) q=rotp(q,r);
31
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
32
+ for(auto &q:v){minx=min(minx,q.first);miny=min(miny,q.second);maxx=max(maxx,q.first);maxy=max(maxy,q.second);}
33
+ vector<pair<int,int>> v2=v; for(auto &q:v2){q.first-=minx;q.second-=miny;}
34
+ sort(v2.begin(),v2.end());
35
+ string key; key.reserve(v2.size()*8);
36
+ for(auto &q:v2){key.append(to_string(q.first));key.push_back(',');key.append(to_string(q.second));key.push_back(';');}
37
+ if(seen.insert(key).second){
38
+ T t; t.w=maxx-minx+1; t.h=maxy-miny+1; t.c=v2; t.r=r; t.f=rf; t.minx=minx; t.miny=miny;
39
+ t.lo.assign(t.w,INT_MAX); t.hi.assign(t.w,INT_MIN);
40
+ for(auto &q:v2){int x=q.first,y=q.second; if(t.lo[x]>y) t.lo[x]=y; if(t.hi[x]<y) t.hi[x]=y;}
41
+ p.t.push_back(move(t));
42
+ }
43
+ }
44
+ }
45
+ for(auto &t:p.t){p.minW=min(p.minW,t.w); p.minH=min(p.minH,t.h); p.minA=min(p.minA,t.w*t.h);}
46
+ if(p.t.empty()){T t; t.w=1;t.h=1;t.c={{0,0}};t.lo={0};t.hi={0};t.r=0;t.f=0;t.minx=0;t.miny=0;p.t.push_back(t);p.minW=1;p.minH=1;p.minA=1;}
47
+ }
48
+ vector<int> idx(n); iota(idx.begin(),idx.end(),0);
49
+ unsigned long long seed=((unsigned long long)chrono::high_resolution_clock::now().time_since_epoch().count()) ^ (S<<1) ^ (unsigned long long)(n*1469598103934665603ULL);
50
+ RNG rng(seed);
51
+ auto ord4 = [&]() {
52
+ vector<int> res = idx;
53
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
54
+ int da = min(ps[a].minW, ps[a].minH);
55
+ int db = min(ps[b].minW, ps[b].minH);
56
+ if (da != db) return da < db;
57
+ if (ps[a].k != ps[b].k) return ps[a].k < ps[b].k;
58
+ return ps[a].id > ps[b].id;
59
+ });
60
+ return res;
61
+ };
62
+ auto pack=[&](int W,const vector<int>& o0,RNG &rng,bool randtie){
63
+ vector<int> h(W,-1);
64
+ long long g=-1;
65
+ vector<Pl> pl; pl.reserve(o0.size());
66
+ vector<int> o=o0;
67
+ int t=0,nm=(int)o.size();
68
+ bool big=S>3000;
69
+ int maxBound=max(1,n/4);
70
+ int expLIM=min(maxBound,(int)(350000/max(1LL,S-3500)));
71
+ int dynLIM=big?expLIM:maxBound;
72
+ auto tStart=chrono::steady_clock::now();
73
+ auto batchStart=tStart;
74
+ long long TLms=big?1700:LLONG_MAX/4;
75
+ int stepCnt=0;
76
+ while(t<nm){
77
+ int limCnt=max(1,dynLIM);
78
+ int lim=min(nm,t+limCnt);
79
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t; int bestid=-1;
80
+ for(int pos=t;pos<lim;pos++){
81
+ int id=o[pos];
82
+ auto &p=ps[id];
83
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
84
+ for(int ti=0;ti<(int)p.t.size();ti++){
85
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
86
+ for(int x0=0;x0<Rpos;x0++){
87
+ int y0=0;
88
+ for(int j=0;j<tsh.w;j++){
89
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
90
+ }
91
+ int nhbuf[32];
92
+ int l=-1; long long dsum=0;
93
+ for(int j=0;j<tsh.w;j++){
94
+ int nh=h[x0+j];
95
+ if(tsh.hi[j]!=INT_MIN){
96
+ int cand=y0+tsh.hi[j];
97
+ if(nh<cand) nh=cand;
98
+ }
99
+ nhbuf[j]=nh;
100
+ if(nh>l) l=nh;
101
+ }
102
+ for(int j=0;j<tsh.w;j++){
103
+ int inc=nhbuf[j]-h[x0+j];
104
+ if(inc>0) dsum+=inc;
105
+ }
106
+ long long dr=0;
107
+ if(x0>0){
108
+ long long old=llabs((long long)h[x0]-h[x0-1]);
109
+ long long nw=llabs((long long)nhbuf[0]-h[x0-1]);
110
+ dr+=nw-old;
111
+ }
112
+ for(int j=0;j<tsh.w-1;j++){
113
+ long long old=llabs((long long)h[x0+j+1]-h[x0+j]);
114
+ long long nw=llabs((long long)nhbuf[j+1]-nhbuf[j]);
115
+ dr+=nw-old;
116
+ }
117
+ if(x0+tsh.w<W){
118
+ long long old=llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);
119
+ long long nw=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1]);
120
+ dr+=nw-old;
121
+ }
122
+ long long gg=g; if(gg<l) gg=l;
123
+ bool take=false;
124
+ if(gg<bestg2) take=true;
125
+ else if(gg==bestg2){
126
+ if(dsum<bds2) take=true;
127
+ else if(dsum==bds2){
128
+ if(l<bl2) take=true;
129
+ else if(l==bl2){
130
+ if(dr<bdr2) take=true;
131
+ else if(dr==bdr2){
132
+ if(y0<by02) take=true;
133
+ else if(y0==by02){
134
+ if(x0<bx02) take=true;
135
+ else if(x0==bx02 && randtie && rng.coin()) take=true;
136
+ }
137
+ }
138
+ }
139
+ }
140
+ }
141
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=y0;bl2=l;bds2=dsum;bdr2=dr;by02=y0;bx02=x0;}
142
+ }
143
+ }
144
+ if(bti2==-1) continue;
145
+ bool take=false;
146
+ if(bestg2<bestg) take=true;
147
+ else if(bestg2==bestg){
148
+ if(bds2<bds) take=true;
149
+ else if(bds2==bds){
150
+ if(bl2<bl) take=true;
151
+ else if(bl2==bl){
152
+ if(bdr2<bdr) take=true;
153
+ else if(bdr2==bdr){
154
+ if(by02<by0) take=true;
155
+ else if(by02==by0){
156
+ if(bx02<bx0) take=true;
157
+ else if(bx02==bx0 && randtie && rng.coin()) take=true;
158
+ }
159
+ }
160
+ }
161
+ }
162
+ }
163
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=bds2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
164
+ }
165
+ if(bti==-1){t++;stepCnt++;if(big&&stepCnt==5){auto now=chrono::steady_clock::now(); auto elapsed=chrono::duration<double,milli>(now-tStart).count(); auto batch=chrono::duration<double,milli>(now-batchStart).count(); double remT=max(0.0,TLms-elapsed); int remSteps=max(1,nm-t); double budget=remT*5.0/remSteps; if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1); batchStart=now; stepCnt=0;} continue;}
166
+ auto &tsh=ps[bestid].t[bti];
167
+ for(int j=0;j<tsh.w;j++){
168
+ int nh=h[bx+j];
169
+ if(tsh.hi[j]!=INT_MIN){
170
+ int cand=by+tsh.hi[j];
171
+ if(nh<cand) nh=cand;
172
+ }
173
+ h[bx+j]=nh;
174
+ }
175
+ if(g<bl) g=bl;
176
+ pl.push_back({bestid,bti,bx,by});
177
+ if(bestpos!=t) swap(o[t],o[bestpos]);
178
+ t++;
179
+ stepCnt++;
180
+ if(big&&stepCnt==5){
181
+ auto now=chrono::steady_clock::now();
182
+ auto elapsed=chrono::duration<double,milli>(now-tStart).count();
183
+ auto batch=chrono::duration<double,milli>(now-batchStart).count();
184
+ double remT=max(0.0,TLms-elapsed);
185
+ int remSteps=max(1,nm-t);
186
+ double budget=remT*5.0/remSteps;
187
+ if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
188
+ batchStart=now;
189
+ stepCnt=0;
190
+ }
191
+ }
192
+ int H=(int)g+1;
193
+ int maxX=-1;
194
+ for(auto &pp:pl){
195
+ auto &t=ps[pp.idx].t[pp.ti];
196
+ for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}
197
+ }
198
+ int Wused=0;
199
+ if(maxX>=0){
200
+ vector<char> used(maxX+1,false);
201
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}}
202
+ for(int x=0;x<=maxX;x++) if(used[x]) Wused++;
203
+ }
204
+ int Wfinal=max(0,Wused);
205
+ long long A=1LL*H*max(1,Wfinal);
206
+ return R{A,max(1,Wfinal),H,move(pl)};
207
+ };
208
+ int minW=0; for(auto &p:ps) minW=max(minW,p.minW);
209
+ double factor;
210
+ if (S < 1000) {
211
+ factor = 0.4;
212
+ } else if (S < 3000) {
213
+ factor = 0.5;
214
+ } else if (S < 10000) {
215
+ factor = 0.27;
216
+ } else if (S < 30000) {
217
+ factor = 0.08;
218
+ } else {
219
+ factor = 0.01;
220
+ }
221
+ int base = max(minW, (int)floor(sqrt((double)S * factor)));
222
+ vector<int> Ws;
223
+ {
224
+ unordered_set<int> used; used.reserve(512);
225
+ auto addW=[&](int w){if(w<minW) w=minW; if(used.insert(w).second) Ws.push_back(w);};
226
+ addW(base);
227
+ int span=min(128,max(30,base));
228
+ for(int d=1;d<=span;d++){addW(base-d); addW(base+d);}
229
+ addW(minW);
230
+ addW((int)max<long long>(minW,(S+base-1)/base));
231
+ for(int m=2;m<=6;m++){addW(base*m/3); addW((int)max<long long>(minW,S/((base*m/3)?(base*m/3):1)));}
232
+ sort(Ws.begin(),Ws.end(),[&](int a,int b){int da=abs(a-base),db=abs(b-base); if(da!=db) return da<db; return a<b;});
233
+ }
234
+ long long bestA=LLONG_MAX; int bestW=0,bestH=0; R bestR; bool hasBestmine=false;
235
+ auto t0=chrono::steady_clock::now();
236
+ const double TL=1800.0;
237
+ double avg=250.0; int cnt=0;
238
+ for(int wi=0;wi<(int)Ws.size();wi++){
239
+ auto now=chrono::steady_clock::now();
240
+ double used=chrono::duration<double,milli>(now-t0).count();
241
+ if(used+avg*1.3>TL) break;
242
+ int W=Ws[wi];
243
+ vector<vector<int>> orders;
244
+ orders.push_back(ord4());
245
+ int oi=0;
246
+ while(oi<(int)orders.size()){
247
+ auto t1=chrono::steady_clock::now();
248
+ double used2=chrono::duration<double,milli>(t1-t0).count();
249
+ if(used2+avg*1.15>TL) break;
250
+ bool randtie=(oi>=1);
251
+ R r=pack(W,orders[oi],rng,randtie);
252
+ auto t2=chrono::steady_clock::now();
253
+ double dt=chrono::duration<double,milli>(t2-t1).count();
254
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
255
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
256
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
257
+ }
258
+ oi++;
259
+ }
260
+ }
261
+ if(!hasBestmine){
262
+ int W=max(minW,(int)floor(sqrt((double)S)));
263
+ auto o=ord4();
264
+ R r=pack(W,o,rng,false);
265
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
266
+ }
267
+ // Adaptive W2: compute eff-optimal width and try if time remains
268
+ if(hasBestmine && bestW>0 && bestH>0){
269
+ auto now=chrono::steady_clock::now();
270
+ double used=chrono::duration<double,milli>(now-t0).count();
271
+ if(used+avg*1.3<TL){
272
+ double eff=(double)S/((double)bestW*bestH);
273
+ if(eff>0.3&&eff<1.0){
274
+ // Optimal width for eff: W*H = S/eff, with H = S/(W*eff)
275
+ // Want to find W that minimizes W*H given eff varies
276
+ // Use current eff estimate: try W2 = S/bestH (so that H2 ≈ bestW)
277
+ int W2=max(minW,(int)max<long long>(minW,S/bestH));
278
+ if(abs(W2-base)>2){
279
+ auto o=ord4();
280
+ R r=pack(W2,o,rng,false);
281
+ if(r.A<bestA||(r.A==bestA&&(r.H<bestH||(r.H==bestH&&r.W<bestW)))){
282
+ bestA=r.A;bestW=r.W;bestH=r.H;bestR=r;
283
+ }
284
+ }
285
+ }
286
+ }
287
+ }
288
+ // Random tie-breaking trials at promising widths with remaining time
289
+ if(hasBestmine){
290
+ vector<int> trialWs;
291
+ trialWs.push_back(base);
292
+ if(bestH>0){int w2=max(minW,(int)max<long long>(minW,S/bestH));if(w2!=base)trialWs.push_back(w2);}
293
+ trialWs.push_back(max(minW,base-1));
294
+ trialWs.push_back(base+1);
295
+ int ti=0;
296
+ for(auto now=chrono::steady_clock::now();
297
+ chrono::duration<double,milli>(now-t0).count()+avg*2.0<TL;
298
+ now=chrono::steady_clock::now()){
299
+ int W=trialWs[ti%trialWs.size()];ti++;
300
+ auto o=ord4();
301
+ R r=pack(W,o,rng,true);
302
+ if(r.A<bestA||(r.A==bestA&&(r.H<bestH||(r.H==bestH&&r.W<bestW)))){
303
+ bestA=r.A;bestW=r.W;bestH=r.H;bestR=r;
304
+ }
305
+ }
306
+ }
307
+ int maxX=-1;
308
+ for(auto &p:bestR.pl){
309
+ auto &t=ps[p.idx].t[p.ti];
310
+ for(auto &q:t.c){int x=p.x+q.first; if(x>maxX) maxX=x;}
311
+ }
312
+ vector<int> mapx(maxX+1,-1);
313
+ if(maxX>=0){
314
+ vector<char> used(maxX+1,false);
315
+ for(auto &p:bestR.pl){
316
+ auto &t=ps[p.idx].t[p.ti];
317
+ for(auto &q:t.c){used[p.x+q.first]=true;}
318
+ }
319
+ int cur=0;
320
+ for(int x=0;x<=maxX;x++) if(used[x]) mapx[x]=cur++;
321
+ }
322
+ vector<array<int,4>> ans(n,{0,0,0,0});
323
+ for(auto &p:bestR.pl){
324
+ auto &t=ps[p.idx].t[p.ti];
325
+ int bx = (mapx.empty()?p.x:mapx[p.x]);
326
+ int Xi = bx - t.minx;
327
+ int Yi = p.y - t.miny;
328
+ int Ri = (4 - (t.r%4) + 4) % 4;
329
+ int Fi = t.f;
330
+ ans[p.idx]={Xi,Yi,Ri,Fi};
331
+ }
332
+ cout<<bestR.W<<" "<<bestR.H<<"\n";
333
+ for(int i=0;i<n;i++){
334
+ cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<"\n";
335
+ }
336
+ return 0;
337
+ }
docker_space/frontier_cs_0_polyomino/0/chk.cc ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Polyomino Packing (Reflections Allowed) — Checker (updated to new statement)
2
+ // Uses testlib: https://codeforces.com/blog/entry/18431
3
+ //
4
+ // Validates a participant's output for a single test case.
5
+ //
6
+ // Problem statement deltas reflected here:
7
+ // - n ∈ [100, 10000]
8
+ // - k_i ∈ [1, 10]
9
+ // - Σk_i ≤ 2000 (enforced)
10
+ // - Scoring per test: score = 1e5 * (Σk_i) / (W*H) (higher is better)
11
+ //
12
+ // Input (from problem):
13
+ // Line 1: n
14
+ // For each i=1..n:
15
+ // Line: k_i
16
+ // Next k_i lines: x y (integers; define a polyomino in local coords)
17
+ //
18
+ // Output (participant):
19
+ // Line 1: W H
20
+ // Then n lines (one per polyomino i):
21
+ // X_i Y_i R_i F_i
22
+ // R_i ∈ {0,1,2,3} = # of 90° clockwise rotations
23
+ // F_i ∈ {0,1} = reflection flag (1 = reflect across y-axis)
24
+ // Transform order (must): reflect → rotate → translate.
25
+ //
26
+ // Checks performed:
27
+ // - Token counts and ranges (R_i, F_i in valid sets)
28
+ // - After transform, every cell in [0, W) × [0, H)
29
+ // - No overlapping occupied grid cells between pieces
30
+ // Scoring message: Score = Σk_i / (W*H)
31
+
32
+ #include "testlib.h"
33
+ #include <bits/stdc++.h>
34
+ using namespace std;
35
+
36
+ struct CellHash {
37
+ size_t operator()(const pair<long long,long long>& p) const noexcept {
38
+ uint64_t x = static_cast<uint64_t>(p.first);
39
+ uint64_t y = static_cast<uint64_t>(p.second);
40
+ // splitmix-style mixing
41
+ x ^= y + 0x9e3779b97f4a7c15ULL + (x<<6) + (x>>2);
42
+ x ^= x >> 30; x *= 0xbf58476d1ce4e5b9ULL;
43
+ x ^= x >> 27; x *= 0x94d049bb133111ebULL;
44
+ x ^= x >> 31;
45
+ return static_cast<size_t>(x);
46
+ }
47
+ };
48
+
49
+ static inline pair<long long,long long> rot90cw(long long x, long long y, int r) {
50
+ switch (r & 3) {
51
+ case 0: return { x, y};
52
+ case 1: return { y, -x};
53
+ case 2: return {-x, -y};
54
+ default: return {-y, x};
55
+ }
56
+ }
57
+
58
+ int main(int argc, char* argv[]) {
59
+ registerTestlibCmd(argc, argv);
60
+
61
+ // ===== Read input =====
62
+ const int n = inf.readInt(100, 10000, "n");
63
+
64
+ vector<vector<pair<long long,long long>>> shapes(n);
65
+ long long totalCells = 0;
66
+
67
+ for (int i = 0; i < n; ++i) {
68
+ int k = inf.readInt(1, 10, "k_i");
69
+ shapes[i].reserve(k);
70
+ for (int j = 0; j < k; ++j) {
71
+ long long x = inf.readLong(numeric_limits<long long>::min()/4,
72
+ numeric_limits<long long>::max()/4, "x_ij");
73
+ long long y = inf.readLong(numeric_limits<long long>::min()/4,
74
+ numeric_limits<long long>::max()/4, "y_ij");
75
+ shapes[i].push_back({x, y});
76
+ }
77
+ totalCells += k;
78
+ }
79
+
80
+ // ===== Read participant output =====
81
+ // Allow large W/H to avoid artificial limits; still within signed 64-bit
82
+ long long W = ouf.readLong(1, (long long)4e12, "W");
83
+ long long H = ouf.readLong(1, (long long)4e12, "H");
84
+
85
+ struct Place { long long X, Y; int R; int F; };
86
+ vector<Place> place(n);
87
+ for (int i = 0; i < n; ++i) {
88
+ long long X = ouf.readLong(-(long long)4e12, (long long)4e12, "X_i");
89
+ long long Y = ouf.readLong(-(long long)4e12, (long long)4e12, "Y_i");
90
+ int R = ouf.readInt(0, 3, "R_i");
91
+ int F = ouf.readInt(0, 1, "F_i");
92
+ place[i] = {X, Y, R, F};
93
+ }
94
+
95
+ if (!ouf.seekEof()) {
96
+ quitf(_pe, "Extra data after expected %d placement lines", n);
97
+ }
98
+
99
+ // ===== Validate placement =====
100
+ unordered_set<pair<long long,long long>, CellHash> occ;
101
+ occ.reserve(static_cast<size_t>(max<long long>(16, totalCells * 2)));
102
+
103
+ auto inBounds = [&](long long x, long long y) -> bool {
104
+ return x >= 0 && y >= 0 && x < W && y < H;
105
+ };
106
+
107
+ for (int i = 0; i < n; ++i) {
108
+ const auto [X, Y, R, F] = place[i];
109
+ for (const auto& c : shapes[i]) {
110
+ long long sx = c.first, sy = c.second;
111
+
112
+ // reflect across y-axis if F=1: (x, y) -> (-x, y)
113
+ long long rx = (F == 1 ? -sx : sx);
114
+ long long ry = sy;
115
+
116
+ // rotate r times 90° CW about origin
117
+ auto [qx, qy] = rot90cw(rx, ry, R);
118
+
119
+ // translate by (X, Y) with overflow checks
120
+ long long gx, gy;
121
+ if (__builtin_add_overflow(qx, X, &gx) ||
122
+ __builtin_add_overflow(qy, Y, &gy)) {
123
+ quitf(_wa, "Overflow after transforming piece %d", i+1);
124
+ }
125
+
126
+ if (!inBounds(gx, gy)) {
127
+ quitf(_wa,
128
+ "Out of bounds: piece %d cell -> (%lld,%lld) not in [0,%lld)×[0,%lld)",
129
+ i+1, gx, gy, W, H);
130
+ }
131
+
132
+ auto ins = occ.insert({gx, gy});
133
+ if (!ins.second) {
134
+ quitf(_wa, "Overlap at cell (%lld,%lld)", gx, gy);
135
+ }
136
+ }
137
+ }
138
+
139
+ // ===== Scoring message =====
140
+ // Use 128-bit to avoid overflow in W*H
141
+ __int128 area128 = (__int128)W * (__int128)H;
142
+ if (area128 <= 0) quitf(_wa, "Non-positive area (W*H)");
143
+ long long area;
144
+ if (area128 > numeric_limits<long long>::max())
145
+ quitf(_wa, "Area overflow: W*H exceeds 64-bit");
146
+ area = (long long)area128;
147
+
148
+ double score = (double) totalCells / (double) area;
149
+ // Include "Ratio:" in message so judge system can parse the partial score
150
+ quitp(score, "Ratio: %.9f (cells=%lld, W=%lld, H=%lld, area=%lld)",
151
+ score, totalCells, W, H, area);
152
+ }
docker_space/frontier_cs_0_polyomino/0/config.yaml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ type: default
3
+ checker: chk.cc
4
+
5
+ # Time and memory limits still apply to the contestant's solution
6
+ time: 2s
7
+ memory: 256m
8
+
9
+ # The subtasks section works the same way
10
+ subtasks:
11
+ - score: 100
12
+ n_cases: 70
docker_space/frontier_cs_0_polyomino/0/evaluate.md ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Evaluation Guide (Inside Container)
2
+
3
+ ## Judge Service
4
+
5
+ The evaluation runs via a go-judge HTTP service accessible inside the container at:
6
+
7
+ ```
8
+ http://Competitive-Programming:8081
9
+ ```
10
+
11
+ ## How to Evaluate a Solution
12
+
13
+ ### Step 1: Submit
14
+
15
+ ```bash
16
+ curl -s -X POST http://Competitive-Programming:8081/submit \
17
+ -F "code=@solution.cpp" \
18
+ -F "pid=0" \
19
+ -F "lang=cpp"
20
+ ```
21
+
22
+ Returns: `{"sid": 1}` — the submission ID.
23
+
24
+ ### Step 2: Poll Result
25
+
26
+ ```bash
27
+ curl -s http://Competitive-Programming:8081/result/<sid>
28
+ ```
29
+
30
+ Poll every 2-3 seconds until `status` is `"done"` or `"error"`.
31
+
32
+ ### Response Format
33
+
34
+ Success:
35
+ ```json
36
+ {
37
+ "status": "done",
38
+ "score": 74.84,
39
+ "scoreUnbounded": 74.84,
40
+ ...
41
+ }
42
+ ```
43
+
44
+ Error (compile error, runtime error, etc.):
45
+ ```json
46
+ {
47
+ "status": "error",
48
+ "error": "...",
49
+ "message": "..."
50
+ }
51
+ ```
52
+
53
+ ## Scoring
54
+
55
+ - Per test case: `score = 1e5 * Σk_i / (W * H)` (higher is better)
56
+ - 70 test cases total, final score is the average across all cases
57
+ - The score is bounded to [0, 100]
58
+
59
+ ## One-Liner Example
60
+
61
+ ```bash
62
+ # Submit and poll
63
+ SID=$(curl -s -X POST http://Competitive-Programming:8081/submit \
64
+ -F "code=@solution.cpp" -F "pid=0" -F "lang=cpp" | python3 -c "import sys,json; print(json.load(sys.stdin)['sid'])")
65
+
66
+ # Wait and get result
67
+ sleep 15 && curl -s http://Competitive-Programming:8081/result/$SID | python3 -m json.tool
68
+ ```
69
+
70
+ ## Notes
71
+
72
+ - The solution must be C++ and compile with g++
73
+ - Time limit: 2 seconds per test case
74
+ - Memory limit: 256 MB
75
+ - The judge compiles the solution once, then runs it against all 70 test cases
76
+ - Problem data is in `/workspace/problem/0/` (statement.txt, testdata/, chk.cc)
docker_space/frontier_cs_0_polyomino/0/examples/gpt5.cpp ADDED
@@ -0,0 +1,271 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <bits/stdc++.h>
2
+ using namespace std;
3
+
4
+ struct Cell { int x, y; };
5
+ struct Transform { int R, F; }; // reflect (y-axis) then rotate R*90° CW
6
+ struct Oriented {
7
+ vector<Cell> pts; // normalized: minx=miny=0
8
+ int w, h;
9
+ int offx, offy; // = -minx, -miny (to undo normalization for output)
10
+ Transform tf;
11
+ };
12
+ struct Piece {
13
+ int id;
14
+ vector<Cell> base;
15
+ vector<Oriented> variants;
16
+ int area;
17
+ };
18
+
19
+ static inline uint64_t pack_xy(int x,int y){
20
+ return (uint64_t(uint32_t(x))<<32) | uint32_t(y);
21
+ }
22
+ static inline pair<int,int> apply_transform(int x,int y,int F,int R){
23
+ if (F) x = -x;
24
+ switch (R & 3){
25
+ case 0: return { x, y};
26
+ case 1: return { y, -x}; // 90 CW
27
+ case 2: return {-x, -y}; // 180
28
+ default:return {-y, x}; // 270 CW
29
+ }
30
+ }
31
+ static Oriented make_oriented(const vector<Cell>& base,int F,int R){
32
+ vector<Cell> t; t.reserve(base.size());
33
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
34
+ for (auto &c: base){
35
+ auto [tx,ty]=apply_transform(c.x,c.y,F,R);
36
+ minx=min(minx,tx); miny=min(miny,ty);
37
+ maxx=max(maxx,tx); maxy=max(maxy,ty);
38
+ t.push_back({tx,ty});
39
+ }
40
+ // normalization
41
+ for (auto &c: t){ c.x -= minx; c.y -= miny; }
42
+ int W = maxx-minx+1, H = maxy-miny+1;
43
+ sort(t.begin(), t.end(), [](const Cell&a,const Cell&b){
44
+ if (a.y!=b.y) return a.y<b.y; return a.x<b.x;
45
+ });
46
+ return Oriented{t, W, H, -minx, -miny, Transform{R,F}};
47
+ }
48
+ static void build_variants(Piece& P){
49
+ vector<Oriented> cand; cand.reserve(8);
50
+ for (int F=0;F<=1;++F) for (int R=0;R<4;++R)
51
+ cand.push_back(make_oriented(P.base,F,R));
52
+ // dedup
53
+ vector<Oriented> uniq;
54
+ for (auto &o: cand){
55
+ bool dup=false;
56
+ for (auto &u: uniq){
57
+ if (u.w==o.w && u.h==o.h && u.pts.size()==o.pts.size()){
58
+ bool same=true;
59
+ for (size_t i=0;i<u.pts.size();++i)
60
+ if (u.pts[i].x!=o.pts[i].x || u.pts[i].y!=o.pts[i].y){ same=false; break; }
61
+ if (same){ dup=true; break; }
62
+ }
63
+ }
64
+ if (!dup) uniq.push_back(o);
65
+ }
66
+ P.variants.swap(uniq);
67
+ }
68
+
69
+ struct Placement { int X=0,Y=0,R=0,F=0; int w=0,h=0; int vi=-1; }; // vi = variant index used
70
+ struct PackedSolution { int W=0,H=0; vector<Placement> place; };
71
+
72
+ struct World {
73
+ int W, Hlimit; // square side S; W==Hlimit==S
74
+ vector<int> height;
75
+ unordered_set<uint64_t> occ;
76
+ int maxH=0;
77
+
78
+ World(int S=1){ clear(S); }
79
+ void clear(int S){ W=S; Hlimit=S; height.assign(W,0); occ.clear(); maxH=0; }
80
+
81
+ inline int shelfY(int x,int w) const {
82
+ int y=0; for (int i=0;i<w;++i) y=max(y,height[x+i]); return y;
83
+ }
84
+ inline bool can_place(const Oriented& o,int X,int Y) const {
85
+ if (X<0 || Y<0) return false;
86
+ if (X + o.w > W) return false;
87
+ if (Y + o.h > Hlimit) return false; // enforce square height cap
88
+ for (auto &c: o.pts){
89
+ int gx=X+c.x, gy=Y+c.y;
90
+ if (occ.find(pack_xy(gx,gy))!=occ.end()) return false;
91
+ }
92
+ return true;
93
+ }
94
+ inline void do_place(const Oriented& o,int X,int Y){
95
+ for (auto &c: o.pts){
96
+ int gx=X+c.x, gy=Y+c.y;
97
+ occ.insert(pack_xy(gx,gy));
98
+ height[gx]=max(height[gx], gy+1);
99
+ if (height[gx]>maxH) maxH=height[gx];
100
+ }
101
+ }
102
+ };
103
+
104
+ int main(){
105
+ ios::sync_with_stdio(false);
106
+ cin.tie(nullptr);
107
+
108
+ int n; if(!(cin>>n)) return 0;
109
+ vector<Piece> P(n);
110
+ long long totalCells=0;
111
+ for (int i=0;i<n;++i){
112
+ P[i].id=i;
113
+ int k; cin>>k;
114
+ P[i].base.resize(k);
115
+ for (int j=0;j<k;++j){ int x,y; cin>>x>>y; P[i].base[j]={x,y}; }
116
+ P[i].area=k; totalCells+=k;
117
+ build_variants(P[i]);
118
+ }
119
+
120
+ // Place larger / less flexible first
121
+ vector<int> order(n); iota(order.begin(), order.end(), 0);
122
+ sort(order.begin(), order.end(), [&](int a,int b){
123
+ if (P[a].area!=P[b].area) return P[a].area>P[b].area;
124
+ return P[a].variants.size()<P[b].variants.size();
125
+ });
126
+
127
+ // Lower bound on square side:
128
+ // 1) area bound
129
+ int S_area = (int)ceil(sqrt((long double)totalCells));
130
+ // 2) geometry bound: each piece needs some min side to fit; use min over variants of max(w,h)
131
+ int S_geom = 1;
132
+ for (auto &p: P){
133
+ int need = INT_MAX;
134
+ for (auto &o: p.variants) need = min(need, max(o.w, o.h));
135
+ S_geom = max(S_geom, need);
136
+ }
137
+ int S0 = max(S_area, S_geom);
138
+
139
+ // Generate candidate square sizes; grow if needed
140
+ vector<int> sides = {
141
+ S0,
142
+ max(S0, (int)ceil(1.05*S0)),
143
+ max(S0, (int)ceil(1.15*S0)),
144
+ max(S0, (int)ceil(0.95*S0))
145
+ };
146
+ sort(sides.begin(), sides.end());
147
+ sides.erase(unique(sides.begin(), sides.end()), sides.end());
148
+
149
+ auto better = [](const PackedSolution& A, const PackedSolution& B){
150
+ if (B.W==0) return true;
151
+ long long aA=1LL*A.W*A.H, aB=1LL*B.W*B.H;
152
+ if (aA!=aB) return aA<aB;
153
+ // If equal area (same S), prefer lower max column height (tie-breaker, though W=H).
154
+ if (A.H!=B.H) return A.H<B.H;
155
+ return A.W<B.W;
156
+ };
157
+
158
+ PackedSolution best; best.W=0; best.H=INT_MAX;
159
+
160
+ auto try_with_side = [&](int S)->optional<PackedSolution>{
161
+ World world(S);
162
+ world.occ.reserve((size_t)totalCells*2 + 1024);
163
+ vector<Placement> place(n);
164
+
165
+ for (int idx=0; idx<n; ++idx){
166
+ int i = order[idx];
167
+ auto &piece = P[i];
168
+
169
+ // Favor shorter/taller shapes appropriately
170
+ vector<int> vord(piece.variants.size());
171
+ iota(vord.begin(), vord.end(), 0);
172
+ sort(vord.begin(), vord.end(), [&](int a,int b){
173
+ const auto&A=piece.variants[a], &B=piece.variants[b];
174
+ if (A.h!=B.h) return A.h<B.h;
175
+ if (A.w!=B.w) return A.w>B.w;
176
+ return A.pts.size()>B.pts.size();
177
+ });
178
+
179
+ int bestVi=-1, bestX=-1, bestY=INT_MAX;
180
+
181
+ for (int vi: vord){
182
+ const auto &o = piece.variants[vi];
183
+ if (o.w > world.W || o.h > world.Hlimit) continue;
184
+
185
+ // x scan (try both coarse step and right align)
186
+ int step = max(1, o.w/2);
187
+ for (int x=0; x + o.w <= world.W; x += step){
188
+ int y = world.shelfY(x, o.w);
189
+ if (y + o.h > world.Hlimit) continue; // square cap
190
+ if (y > bestY) continue;
191
+ if (!world.can_place(o, x, y)) continue;
192
+ bestY=y; bestX=x; bestVi=vi;
193
+ }
194
+ int xr = world.W - o.w;
195
+ if (xr>=0){
196
+ int y = world.shelfY(xr, o.w);
197
+ if (y + o.h <= world.Hlimit && y <= bestY && world.can_place(o, xr, y)){
198
+ bestY=y; bestX=xr; bestVi=vi;
199
+ }
200
+ }
201
+ }
202
+
203
+ if (bestVi<0) return {}; // fail for this S
204
+
205
+ const auto &o = piece.variants[bestVi];
206
+ world.do_place(o, bestX, bestY);
207
+ place[i] = {bestX, bestY, o.tf.R, o.tf.F, o.w, o.h, bestVi};
208
+ }
209
+
210
+ // success with this S
211
+ PackedSolution cand;
212
+ cand.W = S;
213
+ cand.H = S; // enforce square
214
+ cand.place.resize(n);
215
+ for (int i=0;i<n;++i) cand.place[i]=place[i];
216
+ return cand;
217
+ };
218
+
219
+ // Try preset candidates
220
+ for (int S : sides){
221
+ if (auto sol = try_with_side(S)){
222
+ if (best.W==0 || better(*sol,best)) best=*sol;
223
+ }
224
+ }
225
+
226
+ // If none worked, escalate S until it does (guaranteed cap: vertical stack height)
227
+ if (best.W==0){
228
+ // Safe upper bound: stack piece heights of a chosen variant each
229
+ int maxW=1, sumH=0;
230
+ for (auto &p: P){
231
+ int wmin=INT_MAX, hmin=INT_MAX;
232
+ for (auto &o: p.variants){
233
+ wmin = min(wmin, o.w);
234
+ hmin = min(hmin, o.h);
235
+ }
236
+ maxW = max(maxW, wmin);
237
+ sumH += hmin;
238
+ }
239
+ int S = max({S0, maxW, sumH}); // square that trivially fits vertical stack
240
+ // grow linearly from S0 to S (usually hits long before)
241
+ for (int s = S0; s <= S; ++s){
242
+ if (auto sol = try_with_side(s)){ best = *sol; break; }
243
+ }
244
+ // If still nothing (extremely unlikely), force a trivial square stack at side S
245
+ if (best.W==0){
246
+ int y=0;
247
+ vector<Placement> pl(n);
248
+ // Use each piece's first variant
249
+ for (int i=0;i<n;++i){
250
+ const auto &o = P[i].variants[0];
251
+ pl[i]={0,y,o.tf.R,o.tf.F,o.w,o.h,0};
252
+ y += o.h;
253
+ }
254
+ int Sforce = max({S, y, maxW});
255
+ best.W = best.H = Sforce;
256
+ best.place = move(pl);
257
+ }
258
+ }
259
+
260
+ // ---- OUTPUT with offset compensation ----
261
+ cout << best.W << " " << best.H << "\n";
262
+ for (int i=0;i<n;++i){
263
+ const auto &pl = best.place[i];
264
+ const auto &o = P[i].variants[pl.vi];
265
+ // t = (X - minx, Y - miny) = (X + offx, Y + offy)
266
+ int Xout = pl.X + o.offx;
267
+ int Yout = pl.Y + o.offy;
268
+ cout << Xout << " " << Yout << " " << pl.R << " " << pl.F << "\n";
269
+ }
270
+ return 0;
271
+ }
docker_space/frontier_cs_0_polyomino/0/examples/reference.cpp ADDED
@@ -0,0 +1,297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ SOURCE: Shang Zhou
3
+ IIMOC SUBMISSION #1443
4
+ HUMAN BEST FOR POLYPACK (TRANSFORMATION OUTPUT FORMAT)
5
+ */
6
+
7
+ #include <bits/stdc++.h>
8
+ using namespace std;
9
+ struct T{int w,h;vector<pair<int,int>> c;vector<int> lo,hi;int r,f,minx,miny;};
10
+ struct P{int id,k;vector<pair<int,int>> b;vector<T> t;int minW=1e9,minH=1e9,minA=1e9;};
11
+ struct Pl{int idx,ti,x,y;};
12
+ struct R{long long A;int W,H;vector<Pl> pl;};
13
+ struct RNG{unsigned long long s;RNG(unsigned long long x){s=x?x:1;}inline unsigned long long nxt(){s^=s<<7;s^=s>>9;return s;}inline int rint(int n){return (int)(nxt()%n);}inline bool coin(){return nxt()&1;}};
14
+ static inline pair<int,int> rotp(pair<int,int> p,int r){if(r==0)return p; if(r==1)return make_pair(-p.second,p.first); if(r==2)return make_pair(-p.first,-p.second); return make_pair(p.second,-p.first);}
15
+ int main(){
16
+ ios::sync_with_stdio(false);
17
+ cin.tie(nullptr);
18
+ int n; if(!(cin>>n)) return 0;
19
+ vector<P> ps(n); long long S=0;
20
+ for(int i=0;i<n;i++){
21
+ int k;cin>>k; ps[i].id=i+1; ps[i].k=k; ps[i].b.resize(k);
22
+ for(int j=0;j<k;j++){int x,y;cin>>x>>y; ps[i].b[j]={x,y};}
23
+ S+=k;
24
+ }
25
+ for(int i=0;i<n;i++){
26
+ auto &p=ps[i]; unordered_set<string> seen; seen.reserve(32);
27
+ for(int rf=0;rf<2;rf++){
28
+ vector<pair<int,int>> src=p.b; if(rf){for(auto &q:src) q.first=-q.first;}
29
+ for(int r=0;r<4;r++){
30
+ vector<pair<int,int>> v=src; for(auto &q:v) q=rotp(q,r);
31
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
32
+ for(auto &q:v){minx=min(minx,q.first);miny=min(miny,q.second);maxx=max(maxx,q.first);maxy=max(maxy,q.second);}
33
+ vector<pair<int,int>> v2=v; for(auto &q:v2){q.first-=minx;q.second-=miny;}
34
+ sort(v2.begin(),v2.end());
35
+ string key; key.reserve(v2.size()*8);
36
+ for(auto &q:v2){key.append(to_string(q.first));key.push_back(',');key.append(to_string(q.second));key.push_back(';');}
37
+ if(seen.insert(key).second){
38
+ T t; t.w=maxx-minx+1; t.h=maxy-miny+1; t.c=v2; t.r=r; t.f=rf; t.minx=minx; t.miny=miny;
39
+ t.lo.assign(t.w,INT_MAX); t.hi.assign(t.w,INT_MIN);
40
+ for(auto &q:v2){int x=q.first,y=q.second; if(t.lo[x]>y) t.lo[x]=y; if(t.hi[x]<y) t.hi[x]=y;}
41
+ p.t.push_back(move(t));
42
+ }
43
+ }
44
+ }
45
+ for(auto &t:p.t){p.minW=min(p.minW,t.w); p.minH=min(p.minH,t.h); p.minA=min(p.minA,t.w*t.h);}
46
+ if(p.t.empty()){T t; t.w=1;t.h=1;t.c={{0,0}};t.lo={0};t.hi={0};t.r=0;t.f=0;t.minx=0;t.miny=0;p.t.push_back(t);p.minW=1;p.minH=1;p.minA=1;}
47
+ }
48
+ vector<int> idx(n); iota(idx.begin(),idx.end(),0);
49
+ unsigned long long seed=((unsigned long long)chrono::high_resolution_clock::now().time_since_epoch().count()) ^ (S<<1) ^ (unsigned long long)(n*1469598103934665603ULL);
50
+ RNG rng(seed);
51
+ auto ord4 = [&]() {
52
+ vector<int> res = idx;
53
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
54
+ int da = min(ps[a].minW, ps[a].minH);
55
+ int db = min(ps[b].minW, ps[b].minH);
56
+ if (da != db) return da < db;
57
+ if (ps[a].k != ps[b].k) return ps[a].k < ps[b].k;
58
+ return ps[a].id > ps[b].id;
59
+ });
60
+ return res;
61
+ };
62
+ auto pack=[&](int W,const vector<int>& o0,RNG &rng,bool randtie){
63
+ vector<int> h(W,-1);
64
+ long long g=-1;
65
+ vector<Pl> pl; pl.reserve(o0.size());
66
+ vector<int> o=o0;
67
+ int t=0,nm=(int)o.size();
68
+ bool big=S>7000;
69
+ int maxBound=max(1,n/4);
70
+ int expLIM=min(maxBound,(int)(350000/max(1LL,S-3500)));
71
+ int dynLIM=big?expLIM:maxBound;
72
+ auto tStart=chrono::steady_clock::now();
73
+ auto batchStart=tStart;
74
+ long long TLms=big?1900:LLONG_MAX/4;
75
+ int stepCnt=0;
76
+ while(t<nm){
77
+ int limCnt=max(1,dynLIM);
78
+ int lim=min(nm,t+limCnt);
79
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t; int bestid=-1;
80
+ for(int pos=t;pos<lim;pos++){
81
+ int id=o[pos];
82
+ auto &p=ps[id];
83
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
84
+ for(int ti=0;ti<(int)p.t.size();ti++){
85
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
86
+ for(int x0=0;x0<Rpos;x0++){
87
+ int y0=0;
88
+ for(int j=0;j<tsh.w;j++){
89
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
90
+ }
91
+ int nhbuf[32];
92
+ int l=-1; long long dsum=0;
93
+ for(int j=0;j<tsh.w;j++){
94
+ int nh=h[x0+j];
95
+ if(tsh.hi[j]!=INT_MIN){
96
+ int cand=y0+tsh.hi[j];
97
+ if(nh<cand) nh=cand;
98
+ }
99
+ nhbuf[j]=nh;
100
+ if(nh>l) l=nh;
101
+ }
102
+ for(int j=0;j<tsh.w;j++){
103
+ int inc=nhbuf[j]-h[x0+j];
104
+ if(inc>0) dsum+=inc;
105
+ }
106
+ long long dr=0;
107
+ if(x0>0){
108
+ long long old=llabs((long long)h[x0]-h[x0-1]);
109
+ long long nw=llabs((long long)nhbuf[0]-h[x0-1]);
110
+ dr+=nw-old;
111
+ }
112
+ for(int j=0;j<tsh.w-1;j++){
113
+ long long old=llabs((long long)h[x0+j+1]-h[x0+j]);
114
+ long long nw=llabs((long long)nhbuf[j+1]-nhbuf[j]);
115
+ dr+=nw-old;
116
+ }
117
+ if(x0+tsh.w<W){
118
+ long long old=llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);
119
+ long long nw=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1]);
120
+ dr+=nw-old;
121
+ }
122
+ long long gg=g; if(gg<l) gg=l;
123
+ bool take=false;
124
+ if(gg<bestg2) take=true;
125
+ else if(gg==bestg2){
126
+ if(dsum<bds2) take=true;
127
+ else if(dsum==bds2){
128
+ if(l<bl2) take=true;
129
+ else if(l==bl2){
130
+ if(dr<bdr2) take=true;
131
+ else if(dr==bdr2){
132
+ if(y0<by02) take=true;
133
+ else if(y0==by02){
134
+ if(x0<bx02) take=true;
135
+ else if(x0==bx02 && randtie && rng.coin()) take=true;
136
+ }
137
+ }
138
+ }
139
+ }
140
+ }
141
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=y0;bl2=l;bds2=dsum;bdr2=dr;by02=y0;bx02=x0;}
142
+ }
143
+ }
144
+ if(bti2==-1) continue;
145
+ bool take=false;
146
+ if(bestg2<bestg) take=true;
147
+ else if(bestg2==bestg){
148
+ if(bds2<bds) take=true;
149
+ else if(bds2==bds){
150
+ if(bl2<bl) take=true;
151
+ else if(bl2==bl){
152
+ if(bdr2<bdr) take=true;
153
+ else if(bdr2==bdr){
154
+ if(by02<by0) take=true;
155
+ else if(by02==by0){
156
+ if(bx02<bx0) take=true;
157
+ else if(bx02==bx0 && randtie && rng.coin()) take=true;
158
+ }
159
+ }
160
+ }
161
+ }
162
+ }
163
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=bds2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
164
+ }
165
+ if(bti==-1){t++;stepCnt++;if(big&&stepCnt==5){auto now=chrono::steady_clock::now(); auto elapsed=chrono::duration<double,milli>(now-tStart).count(); auto batch=chrono::duration<double,milli>(now-batchStart).count(); double remT=max(0.0,TLms-elapsed); int remSteps=max(1,nm-t); double budget=remT*5.0/remSteps; if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1); batchStart=now; stepCnt=0;} continue;}
166
+ auto &tsh=ps[bestid].t[bti];
167
+ for(int j=0;j<tsh.w;j++){
168
+ int nh=h[bx+j];
169
+ if(tsh.hi[j]!=INT_MIN){
170
+ int cand=by+tsh.hi[j];
171
+ if(nh<cand) nh=cand;
172
+ }
173
+ h[bx+j]=nh;
174
+ }
175
+ if(g<bl) g=bl;
176
+ pl.push_back({bestid,bti,bx,by});
177
+ if(bestpos!=t) swap(o[t],o[bestpos]);
178
+ t++;
179
+ stepCnt++;
180
+ if(big&&stepCnt==5){
181
+ auto now=chrono::steady_clock::now();
182
+ auto elapsed=chrono::duration<double,milli>(now-tStart).count();
183
+ auto batch=chrono::duration<double,milli>(now-batchStart).count();
184
+ double remT=max(0.0,TLms-elapsed);
185
+ int remSteps=max(1,nm-t);
186
+ double budget=remT*5.0/remSteps;
187
+ if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
188
+ batchStart=now;
189
+ stepCnt=0;
190
+ }
191
+ }
192
+ int H=(int)g+1;
193
+ int maxX=-1;
194
+ for(auto &pp:pl){
195
+ auto &t=ps[pp.idx].t[pp.ti];
196
+ for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}
197
+ }
198
+ int Wused=0;
199
+ if(maxX>=0){
200
+ vector<char> used(maxX+1,false);
201
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}}
202
+ for(int x=0;x<=maxX;x++) if(used[x]) Wused++;
203
+ }
204
+ int Wfinal=max(0,Wused);
205
+ long long A=1LL*H*max(1,Wfinal);
206
+ return R{A,max(1,Wfinal),H,move(pl)};
207
+ };
208
+ int minW=0; for(auto &p:ps) minW=max(minW,p.minW);
209
+ double factor;
210
+ if (S < 1000) {
211
+ factor = 0.4;
212
+ } else if (S < 3000) {
213
+ factor = 0.5;
214
+ } else if (S < 10000) {
215
+ factor = 0.27;
216
+ } else if (S < 30000) {
217
+ factor = 0.08;
218
+ } else {
219
+ factor = 0.01;
220
+ }
221
+ int base = max(minW, (int)floor(sqrt((double)S * factor)));
222
+ vector<int> Ws;
223
+ {
224
+ unordered_set<int> used; used.reserve(512);
225
+ auto addW=[&](int w){if(w<minW) w=minW; if(used.insert(w).second) Ws.push_back(w);};
226
+ addW(base);
227
+ int span=min(96,max(20,base/2));
228
+ for(int d=1;d<=span;d++){addW(base-d); addW(base+d);}
229
+ addW(minW);
230
+ addW((int)max<long long>(minW,(S+base-1)/base));
231
+ for(int m=2;m<=6;m++){addW(base*m/3); addW((int)max<long long>(minW,S/((base*m/3)?(base*m/3):1)));}
232
+ sort(Ws.begin(),Ws.end(),[&](int a,int b){int da=abs(a-base),db=abs(b-base); if(da!=db) return da<db; return a<b;});
233
+ }
234
+ long long bestA=LLONG_MAX; int bestW=0,bestH=0; R bestR; bool hasBestmine=false;
235
+ auto t0=chrono::steady_clock::now();
236
+ const double TL=1980.0;
237
+ double avg=250.0; int cnt=0;
238
+ for(int wi=0;wi<(int)Ws.size();wi++){
239
+ auto now=chrono::steady_clock::now();
240
+ double used=chrono::duration<double,milli>(now-t0).count();
241
+ if(used+avg*1.3>TL) break;
242
+ int W=Ws[wi];
243
+ vector<vector<int>> orders;
244
+ orders.push_back(ord4());
245
+ int oi=0;
246
+ while(oi<(int)orders.size()){
247
+ auto t1=chrono::steady_clock::now();
248
+ double used2=chrono::duration<double,milli>(t1-t0).count();
249
+ if(used2+avg*1.15>TL) break;
250
+ bool randtie=(oi>=1);
251
+ R r=pack(W,orders[oi],rng,randtie);
252
+ auto t2=chrono::steady_clock::now();
253
+ double dt=chrono::duration<double,milli>(t2-t1).count();
254
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
255
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
256
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
257
+ }
258
+ oi++;
259
+ }
260
+ }
261
+ if(!hasBestmine){
262
+ int W=max(minW,(int)floor(sqrt((double)S)));
263
+ auto o=ord4();
264
+ R r=pack(W,o,rng,false);
265
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
266
+ }
267
+ int maxX=-1;
268
+ for(auto &p:bestR.pl){
269
+ auto &t=ps[p.idx].t[p.ti];
270
+ for(auto &q:t.c){int x=p.x+q.first; if(x>maxX) maxX=x;}
271
+ }
272
+ vector<int> mapx(maxX+1,-1);
273
+ if(maxX>=0){
274
+ vector<char> used(maxX+1,false);
275
+ for(auto &p:bestR.pl){
276
+ auto &t=ps[p.idx].t[p.ti];
277
+ for(auto &q:t.c){used[p.x+q.first]=true;}
278
+ }
279
+ int cur=0;
280
+ for(int x=0;x<=maxX;x++) if(used[x]) mapx[x]=cur++;
281
+ }
282
+ vector<array<int,4>> ans(n,{0,0,0,0});
283
+ for(auto &p:bestR.pl){
284
+ auto &t=ps[p.idx].t[p.ti];
285
+ int bx = (mapx.empty()?p.x:mapx[p.x]);
286
+ int Xi = bx - t.minx;
287
+ int Yi = p.y - t.miny;
288
+ int Ri = (4 - (t.r%4) + 4) % 4;
289
+ int Fi = t.f;
290
+ ans[p.idx]={Xi,Yi,Ri,Fi};
291
+ }
292
+ cout<<bestR.W<<" "<<bestR.H<<"\n";
293
+ for(int i=0;i<n;i++){
294
+ cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<"\n";
295
+ }
296
+ return 0;
297
+ }
docker_space/frontier_cs_0_polyomino/0/statement.txt ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Pack the Polyominoes (Reflections Allowed)
2
+
3
+ ## Problem
4
+ You are given a set of n polyominoes placed on a unit square grid. Each polyomino consists of between 1 and 10 unit cells, connected edge-to-edge (4-connectivity). Your task is to place all polyominoes—allowing **rotations, reflections, and translations**—into an axis-aligned rectangle of the grid with no overlaps and no cells outside the rectangle, minimizing the rectangle’s area.
5
+
6
+ A placement specifies, for every polyomino, an integer translation, an optional reflection, and a rotation by a multiple of 90°, such that:
7
+
8
+ - every cell lands on integer grid coordinates,
9
+ - no two placed cells overlap,
10
+ - all placed cells lie within a single axis-aligned rectangle of width W and height H.
11
+
12
+ The objective is to minimize A = W × H. In case of ties on area, prefer smaller H, then smaller W.
13
+
14
+ ---
15
+
16
+ ## Input Format
17
+ - Line 1: integer n (100 <= n <= 10^4) — number of polyominoes.
18
+ - For each polyomino i = 1 … n:
19
+ - One line: integer kᵢ (1 ≤ kᵢ ≤ 10) — number of cells.
20
+ - Next kᵢ lines: two integers xᵢⱼ, yᵢⱼ — cell coordinates in the polyomino’s local frame.
21
+ These coordinates define a 4-connected polyomino.
22
+
23
+ Notes:
24
+ - Coordinates may be negative.
25
+ - Shapes may have internal holes.
26
+ - Shapes are defined by structure; initial placement does not matter.
27
+
28
+ ---
29
+
30
+ ## Output Format
31
+ - Line 1: two integers W and H — width and height of the chosen rectangle.
32
+ - Then n lines — one per polyomino i, each containing:
33
+ $$X_i\ Y_i\ R_i\ F_i$$
34
+
35
+ Where:
36
+ - (Xᵢ, Yᵢ): integer translation
37
+ - Rᵢ ∈ {0,1,2,3}: number of 90° clockwise rotations
38
+ - Fᵢ ∈ {0,1}: reflection flag (**1 = reflect across the y-axis before rotation**, 0 = no reflection)
39
+
40
+ All transformed cells must satisfy:
41
+ 0 ≤ xᵢⱼ′ < W, 0 ≤ yᵢⱼ′ < H, W=H
42
+
43
+ ---
44
+
45
+ ## Rules
46
+ 1. All cells occupy unit squares with integer coordinates.
47
+ 2. **Allowed transforms: reflection (optional) → rotation (0°, 90°, 180°, 270°) → translation (in that order).**
48
+ 3. Distinct polyomino cells must not overlap.
49
+ 4. Every cell must lie inside [0, W) × [0, H).
50
+ 5. Scoring: Minimize A = W × H.
51
+
52
+ ---
53
+
54
+ ## Constraints
55
+ - 100 ≤ n ≤ 10000
56
+ - 1 ≤ kᵢ ≤ 10
57
+
58
+ ---
59
+
60
+ ## Validation
61
+ A solution is valid if:
62
+ - All rules are satisfied.
63
+ - The judge verifies non-overlap and bounding-box compliance.
64
+
65
+ ---
66
+
67
+ ## Scoring (for heuristic / leaderboard contests)
68
+ - Per test case: score = 1e5*Σkᵢ/A
69
+ - Any invalid test case → entire submission rejected
70
+
71
+ ---
72
+
73
+ ## Example
74
+
75
+ Input
76
+ ```
77
+ 3
78
+ 1
79
+ 0 0
80
+ 3
81
+ 0 0
82
+ 1 0
83
+ 0 1
84
+ 4
85
+ 0 0
86
+ 1 0
87
+ 0 1
88
+ 1 1
89
+ ```
90
+
91
+ Output
92
+ ```
93
+ 3 3
94
+ 0 0 0 0
95
+ 2 0 1 0
96
+ 1 1 0 0
97
+ ```
98
+
99
+ This places the monomino at (0,0), rotates the triomino by 90° (R=1), and fits all shapes into a 3×3 rectangle. (Reflections are allowed, but not used in this example: F=0.)
100
+
101
+ ---
102
+
103
+ ## Generation
104
+
105
+ Let $S$ be the set of all pieces from size 1-10. Each piece is chosen uniformly at random with replacement from $S$.
106
+
107
+ $n$ is chosen as $10^p$, where $p \sim U(2, 4)$.
docker_space/frontier_cs_0_polyomino_ev2/.claude/settings.local.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "permissions": {
3
+ "deny": [
4
+ "WebSearch",
5
+ "WebFetch"
6
+ ]
7
+ }
8
+ }
docker_space/frontier_cs_0_polyomino_ev2/best/best.cpp ADDED
@@ -0,0 +1,535 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Gen 1: Multiple orderings + improved width search
3
+ Based on reference.cpp with:
4
+ - 4 ordering strategies (ascending min dim, descending area, descending max dim, random)
5
+ - Each width tries all orderings (time permitting)
6
+ - Better width candidate generation
7
+ */
8
+ #include <bits/stdc++.h>
9
+ using namespace std;
10
+ struct T{int w,h;vector<pair<int,int>> c;vector<int> lo,hi;int r,f,minx,miny;};
11
+ struct P{int id,k;vector<pair<int,int>> b;vector<T> t;int minW=1e9,minH=1e9,minA=1e9;};
12
+ struct Pl{int idx,ti,x,y;};
13
+ struct R{long long A;int W,H;vector<Pl> pl;};
14
+ struct RNG{unsigned long long s;RNG(unsigned long long x){s=x?x:1;}inline unsigned long long nxt(){s^=s<<7;s^=s>>9;return s;}inline int rint(int n){return (int)(nxt()%n);}inline bool coin(){return nxt()&1;}};
15
+ static inline pair<int,int> rotp(pair<int,int> p,int r){if(r==0)return p; if(r==1)return make_pair(-p.second,p.first); if(r==2)return make_pair(-p.first,-p.second); return make_pair(p.second,-p.first);}
16
+ int main(){
17
+ ios::sync_with_stdio(false);
18
+ cin.tie(nullptr);
19
+ int n; if(!(cin>>n)) return 0;
20
+ vector<P> ps(n); long long S=0;
21
+ for(int i=0;i<n;i++){
22
+ int k;cin>>k; ps[i].id=i+1; ps[i].k=k; ps[i].b.resize(k);
23
+ for(int j=0;j<k;j++){int x,y;cin>>x>>y; ps[i].b[j]={x,y};}
24
+ S+=k;
25
+ }
26
+ for(int i=0;i<n;i++){
27
+ auto &p=ps[i]; unordered_set<string> seen; seen.reserve(32);
28
+ for(int rf=0;rf<2;rf++){
29
+ vector<pair<int,int>> src=p.b; if(rf){for(auto &q:src) q.first=-q.first;}
30
+ for(int r=0;r<4;r++){
31
+ vector<pair<int,int>> v=src; for(auto &q:v) q=rotp(q,r);
32
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
33
+ for(auto &q:v){minx=min(minx,q.first);miny=min(miny,q.second);maxx=max(maxx,q.first);maxy=max(maxy,q.second);}
34
+ vector<pair<int,int>> v2=v; for(auto &q:v2){q.first-=minx;q.second-=miny;}
35
+ sort(v2.begin(),v2.end());
36
+ string key; key.reserve(v2.size()*8);
37
+ for(auto &q:v2){key.append(to_string(q.first));key.push_back(',');key.append(to_string(q.second));key.push_back(';');}
38
+ if(seen.insert(key).second){
39
+ T t; t.w=maxx-minx+1; t.h=maxy-miny+1; t.c=v2; t.r=r; t.f=rf; t.minx=minx; t.miny=miny;
40
+ t.lo.assign(t.w,INT_MAX); t.hi.assign(t.w,INT_MIN);
41
+ for(auto &q:v2){int x=q.first,y=q.second; if(t.lo[x]>y) t.lo[x]=y; if(t.hi[x]<y) t.hi[x]=y;}
42
+ p.t.push_back(move(t));
43
+ }
44
+ }
45
+ }
46
+ for(auto &t:p.t){p.minW=min(p.minW,t.w); p.minH=min(p.minH,t.h); p.minA=min(p.minA,t.w*t.h);}
47
+ if(p.t.empty()){T t; t.w=1;t.h=1;t.c={{0,0}};t.lo={0};t.hi={0};t.r=0;t.f=0;t.minx=0;t.miny=0;p.t.push_back(t);p.minW=1;p.minH=1;p.minA=1;}
48
+ }
49
+ vector<int> idx(n); iota(idx.begin(),idx.end(),0);
50
+ unsigned long long seed=((unsigned long long)chrono::high_resolution_clock::now().time_since_epoch().count()) ^ (S<<1) ^ (unsigned long long)(n*1469598103934665603ULL);
51
+ RNG rng(seed);
52
+
53
+ // Multiple ordering strategies
54
+ auto ord_asc_mindim = [&]() {
55
+ vector<int> res = idx;
56
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
57
+ int da = min(ps[a].minW, ps[a].minH);
58
+ int db = min(ps[b].minW, ps[b].minH);
59
+ if (da != db) return da < db;
60
+ if (ps[a].k != ps[b].k) return ps[a].k < ps[b].k;
61
+ return ps[a].id > ps[b].id;
62
+ });
63
+ return res;
64
+ };
65
+ auto ord_desc_area = [&]() {
66
+ vector<int> res = idx;
67
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
68
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
69
+ int da = min(ps[a].minW, ps[a].minH);
70
+ int db = min(ps[b].minW, ps[b].minH);
71
+ if (da != db) return da > db;
72
+ return ps[a].id < ps[b].id;
73
+ });
74
+ return res;
75
+ };
76
+ auto ord_desc_maxdim = [&]() {
77
+ vector<int> res = idx;
78
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
79
+ int da = max(ps[a].minW, ps[a].minH);
80
+ int db = max(ps[b].minW, ps[b].minH);
81
+ if (da != db) return da > db;
82
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
83
+ return ps[a].id < ps[b].id;
84
+ });
85
+ return res;
86
+ };
87
+ auto ord_desc_bbox = [&]() {
88
+ vector<int> res = idx;
89
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
90
+ if (ps[a].minA != ps[b].minA) return ps[a].minA > ps[b].minA;
91
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
92
+ return ps[a].id < ps[b].id;
93
+ });
94
+ return res;
95
+ };
96
+ auto ord_random = [&]() {
97
+ vector<int> res = idx;
98
+ for(int i=n-1;i>0;i--){
99
+ int j=rng.rint(i+1);
100
+ swap(res[i],res[j]);
101
+ }
102
+ return res;
103
+ };
104
+ // Perturb a given ordering by making random swaps
105
+ auto ord_perturb = [&](const vector<int>& base_ord, int nswaps) {
106
+ vector<int> res = base_ord;
107
+ for(int i=0;i<nswaps;i++){
108
+ int a=rng.rint(n), b=rng.rint(n);
109
+ swap(res[a],res[b]);
110
+ }
111
+ return res;
112
+ };
113
+ // Sort by flexibility (fewer variants first = harder to place)
114
+ auto ord_flexibility = [&]() {
115
+ vector<int> res = idx;
116
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
117
+ int va=(int)ps[a].t.size(), vb=(int)ps[b].t.size();
118
+ if(va!=vb) return va<vb;
119
+ if(ps[a].k!=ps[b].k) return ps[a].k>ps[b].k;
120
+ return ps[a].id<ps[b].id;
121
+ });
122
+ return res;
123
+ };
124
+
125
+ auto pack=[&](int W,const vector<int>& o0,RNG &rng,bool randtie){
126
+ vector<int> h(W,-1);
127
+ long long g=-1;
128
+ vector<Pl> pl; pl.reserve(o0.size());
129
+ vector<int> o=o0;
130
+ int t=0,nm=(int)o.size();
131
+ bool big=S>7000;
132
+ int maxBound=max(1,n/4);
133
+ int expLIM=min(maxBound,(int)(350000/max(1LL,S-3500)));
134
+ int dynLIM=big?expLIM:maxBound;
135
+ auto tStart=chrono::steady_clock::now();
136
+ auto batchStart=tStart;
137
+ long long TLms=big?1900:LLONG_MAX/4;
138
+ int stepCnt=0;
139
+ while(t<nm){
140
+ // Increase lookahead for early pieces (they have most impact)
141
+ int earlyBoost = (t < nm/10) ? min(3, max(1, maxBound/dynLIM)) : 1;
142
+ int limCnt=max(1,dynLIM * earlyBoost);
143
+ int lim=min(nm,t+limCnt);
144
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t; int bestid=-1;
145
+ for(int pos=t;pos<lim;pos++){
146
+ int id=o[pos];
147
+ auto &p=ps[id];
148
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
149
+ for(int ti=0;ti<(int)p.t.size();ti++){
150
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
151
+ for(int x0=0;x0<Rpos;x0++){
152
+ int y0=0;
153
+ for(int j=0;j<tsh.w;j++){
154
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
155
+ }
156
+ int nhbuf[32];
157
+ int l=-1; long long dsum=0;
158
+ for(int j=0;j<tsh.w;j++){
159
+ int nh=h[x0+j];
160
+ if(tsh.hi[j]!=INT_MIN){
161
+ int cand=y0+tsh.hi[j];
162
+ if(nh<cand) nh=cand;
163
+ }
164
+ nhbuf[j]=nh;
165
+ if(nh>l) l=nh;
166
+ }
167
+ for(int j=0;j<tsh.w;j++){
168
+ int inc=nhbuf[j]-h[x0+j];
169
+ if(inc>0) dsum+=inc;
170
+ }
171
+ long long dr=0;
172
+ if(x0>0){
173
+ long long old=llabs((long long)h[x0]-h[x0-1]);
174
+ long long nw=llabs((long long)nhbuf[0]-h[x0-1]);
175
+ dr+=nw-old;
176
+ }
177
+ for(int j=0;j<tsh.w-1;j++){
178
+ long long old=llabs((long long)h[x0+j+1]-h[x0+j]);
179
+ long long nw=llabs((long long)nhbuf[j+1]-nhbuf[j]);
180
+ dr+=nw-old;
181
+ }
182
+ if(x0+tsh.w<W){
183
+ long long old=llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);
184
+ long long nw=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1]);
185
+ dr+=nw-old;
186
+ }
187
+ long long gg=g; if(gg<l) gg=l;
188
+ bool take=false;
189
+ if(gg<bestg2) take=true;
190
+ else if(gg==bestg2){
191
+ if(dsum<bds2) take=true;
192
+ else if(dsum==bds2){
193
+ if(l<bl2) take=true;
194
+ else if(l==bl2){
195
+ if(dr<bdr2) take=true;
196
+ else if(dr==bdr2){
197
+ if(y0<by02) take=true;
198
+ else if(y0==by02){
199
+ if(x0<bx02) take=true;
200
+ else if(x0==bx02 && randtie && rng.coin()) take=true;
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
206
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=y0;bl2=l;bds2=dsum;bdr2=dr;by02=y0;bx02=x0;}
207
+ }
208
+ }
209
+ if(bti2==-1) continue;
210
+ // Use waste = dsum - k for between-piece comparison (accounts for piece size)
211
+ long long waste2 = bds2 - p.k;
212
+ bool take=false;
213
+ if(bestg2<bestg) take=true;
214
+ else if(bestg2==bestg){
215
+ if(waste2<bds) take=true;
216
+ else if(waste2==bds){
217
+ if(bl2<bl) take=true;
218
+ else if(bl2==bl){
219
+ if(bdr2<bdr) take=true;
220
+ else if(bdr2==bdr){
221
+ if(by02<by0) take=true;
222
+ else if(by02==by0){
223
+ if(bx02<bx0) take=true;
224
+ else if(bx02==bx0 && randtie && rng.coin()) take=true;
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
231
+ }
232
+ if(bti==-1){t++;stepCnt++;if(big&&stepCnt==5){auto now=chrono::steady_clock::now(); auto elapsed=chrono::duration<double,milli>(now-tStart).count(); auto batch=chrono::duration<double,milli>(now-batchStart).count(); double remT=max(0.0,TLms-elapsed); int remSteps=max(1,nm-t); double budget=remT*5.0/remSteps; if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1); batchStart=now; stepCnt=0;} continue;}
233
+ auto &tsh=ps[bestid].t[bti];
234
+ for(int j=0;j<tsh.w;j++){
235
+ int nh=h[bx+j];
236
+ if(tsh.hi[j]!=INT_MIN){
237
+ int cand=by+tsh.hi[j];
238
+ if(nh<cand) nh=cand;
239
+ }
240
+ h[bx+j]=nh;
241
+ }
242
+ if(g<bl) g=bl;
243
+ pl.push_back({bestid,bti,bx,by});
244
+ if(bestpos!=t) swap(o[t],o[bestpos]);
245
+ t++;
246
+ stepCnt++;
247
+ if(big&&stepCnt==5){
248
+ auto now=chrono::steady_clock::now();
249
+ auto elapsed=chrono::duration<double,milli>(now-tStart).count();
250
+ auto batch=chrono::duration<double,milli>(now-batchStart).count();
251
+ double remT=max(0.0,TLms-elapsed);
252
+ int remSteps=max(1,nm-t);
253
+ double budget=remT*5.0/remSteps;
254
+ if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
255
+ batchStart=now;
256
+ stepCnt=0;
257
+ }
258
+ }
259
+ int H=(int)g+1;
260
+ int maxX=-1;
261
+ for(auto &pp:pl){
262
+ auto &t=ps[pp.idx].t[pp.ti];
263
+ for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}
264
+ }
265
+ int Wused=0;
266
+ if(maxX>=0){
267
+ vector<char> used(maxX+1,false);
268
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}}
269
+ for(int x=0;x<=maxX;x++) if(used[x]) Wused++;
270
+ }
271
+ int Wfinal=max(0,Wused);
272
+ long long A=1LL*H*max(1,Wfinal);
273
+ return R{A,max(1,Wfinal),H,move(pl)};
274
+ };
275
+ // Gap-filling pack for small inputs - tries positions below skyline using bitmap
276
+ auto pack_gap=[&](int W,const vector<int>& o0,RNG &rng,bool randtie) -> R {
277
+ int maxHg=(int)(S/max(1,W)+W+50);
278
+ vector<vector<bool>> grid(W, vector<bool>(maxHg, false));
279
+ vector<int> h(W,-1);
280
+ long long g=-1;
281
+ vector<Pl> pl; pl.reserve(o0.size());
282
+ vector<int> o=o0;
283
+ int t2=0,nm=(int)o.size();
284
+ bool big2=(S>7000);
285
+ int maxBound=max(1,n/4);
286
+ int expLIM2=min(maxBound,(int)(350000/max(1LL,S-3500)));
287
+ int dynLIM=big2?expLIM2:maxBound;
288
+ bool gapEnabled=true;
289
+ auto gpTStart=chrono::steady_clock::now();
290
+ auto gpBatchStart=gpTStart;
291
+ long long gpTLms=big2?1800:LLONG_MAX/4;
292
+ int gpStepCnt=0;
293
+ while(t2<nm){
294
+ int earlyBoost=(t2<nm/10)?min(3,max(1,maxBound/max(1,dynLIM))):1;
295
+ int limCnt=max(1,dynLIM*earlyBoost);
296
+ int lim=min(nm,t2+limCnt);
297
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t2; int bestid=-1;
298
+ for(int pos=t2;pos<lim;pos++){
299
+ int id=o[pos];
300
+ auto &p=ps[id];
301
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
302
+ for(int ti=0;ti<(int)p.t.size();ti++){
303
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
304
+ for(int x0=0;x0<Rpos;x0++){
305
+ // Skyline placement
306
+ int y0=0;
307
+ for(int j=0;j<tsh.w;j++){
308
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
309
+ }
310
+ // Also try gap positions (scan up to 10 rows below skyline)
311
+ int gapY=-1;
312
+ if(gapEnabled && y0>0){
313
+ int sd=min(y0,3); // Only check 3 rows below skyline
314
+ for(int gy=max(0,y0-sd);gy<y0;gy++){
315
+ bool ok=true;
316
+ for(auto &q:tsh.c){
317
+ int gx=x0+q.first,gcy=gy+q.second;
318
+ if(gcy<0||gcy>=maxHg||grid[gx][gcy]){ok=false;break;}
319
+ }
320
+ if(ok){gapY=gy;break;}
321
+ }
322
+ }
323
+ // Evaluate both positions
324
+ for(int pass=0;pass<(gapY>=0?2:1);pass++){
325
+ int yy=(pass==0)?y0:gapY;
326
+ int nhbuf[32];
327
+ int l=-1; long long dsum=0;
328
+ for(int j=0;j<tsh.w;j++){
329
+ int nh=h[x0+j];
330
+ if(tsh.hi[j]!=INT_MIN){int cand=yy+tsh.hi[j]; if(nh<cand) nh=cand;}
331
+ nhbuf[j]=nh; if(nh>l) l=nh;
332
+ }
333
+ for(int j=0;j<tsh.w;j++){int inc=nhbuf[j]-h[x0+j]; if(inc>0) dsum+=inc;}
334
+ long long dr=0;
335
+ if(x0>0){dr+=llabs((long long)nhbuf[0]-h[x0-1])-llabs((long long)h[x0]-h[x0-1]);}
336
+ for(int j=0;j<tsh.w-1;j++){dr+=llabs((long long)nhbuf[j+1]-nhbuf[j])-llabs((long long)h[x0+j+1]-h[x0+j]);}
337
+ if(x0+tsh.w<W){dr+=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1])-llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);}
338
+ long long gg=g; if(gg<l) gg=l;
339
+ bool take=false;
340
+ if(gg<bestg2) take=true;
341
+ else if(gg==bestg2){
342
+ if(dsum<bds2) take=true;
343
+ else if(dsum==bds2){if(l<bl2) take=true;
344
+ else if(l==bl2){if(dr<bdr2) take=true;
345
+ else if(dr==bdr2){if(yy<by02) take=true;
346
+ else if(yy==by02){if(x0<bx02) take=true;
347
+ else if(x0==bx02&&randtie&&rng.coin()) take=true;}}}}
348
+ }
349
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=yy;bl2=l;bds2=dsum;bdr2=dr;by02=yy;bx02=x0;}
350
+ }
351
+ }
352
+ }
353
+ if(bti2==-1) continue;
354
+ long long waste2=bds2-p.k;
355
+ bool take=false;
356
+ if(bestg2<bestg) take=true;
357
+ else if(bestg2==bestg){if(waste2<bds) take=true;
358
+ else if(waste2==bds){if(bl2<bl) take=true;
359
+ else if(bl2==bl){if(bdr2<bdr) take=true;
360
+ else if(bdr2==bdr){if(by02<by0) take=true;
361
+ else if(by02==by0){if(bx02<bx0) take=true;
362
+ else if(bx02==bx0&&randtie&&rng.coin()) take=true;}}}}}
363
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
364
+ }
365
+ if(bti==-1){t2++;continue;}
366
+ auto &tsh=ps[bestid].t[bti];
367
+ for(int j=0;j<tsh.w;j++){
368
+ int nh=h[bx+j];
369
+ if(tsh.hi[j]!=INT_MIN){int cand=by+tsh.hi[j]; if(nh<cand) nh=cand;}
370
+ h[bx+j]=nh;
371
+ }
372
+ for(auto &q:tsh.c){int gx=bx+q.first,gy=by+q.second; if(gx>=0&&gx<W&&gy>=0&&gy<maxHg) grid[gx][gy]=true;}
373
+ if(g<bl) g=bl;
374
+ pl.push_back({bestid,bti,bx,by});
375
+ if(bestpos!=t2) swap(o[t2],o[bestpos]);
376
+ t2++;
377
+ gpStepCnt++;
378
+ if(big2&&gpStepCnt==5){
379
+ auto gpNow=chrono::steady_clock::now();
380
+ auto gpElapsed=chrono::duration<double,milli>(gpNow-gpTStart).count();
381
+ auto gpBatch=chrono::duration<double,milli>(gpNow-gpBatchStart).count();
382
+ double gpRemT=max(0.0,(double)gpTLms-gpElapsed);
383
+ int gpRemSteps=max(1,nm-t2);
384
+ double gpBudget=gpRemT*5.0/gpRemSteps;
385
+ if(gpBatch<gpBudget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
386
+ gpBatchStart=gpNow;
387
+ gpStepCnt=0;
388
+ }
389
+ }
390
+ if((int)pl.size() < nm){
391
+ // Not all pieces placed - return failure
392
+ return R{LLONG_MAX, W, 0, {}};
393
+ }
394
+ int H=(int)g+1;
395
+ int maxX=-1;
396
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}}
397
+ int Wused=0;
398
+ if(maxX>=0){vector<char> used(maxX+1,false); for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}} for(int x=0;x<=maxX;x++) if(used[x]) Wused++;}
399
+ int Wfinal=max(0,Wused);
400
+ long long A=1LL*H*max(1,Wfinal);
401
+ return R{A,max(1,Wfinal),H,move(pl)};
402
+ };
403
+ int minW=0; for(auto &p:ps) minW=max(minW,p.minW);
404
+
405
+ // Improved width estimation
406
+ double factor;
407
+ if (S < 1000) factor = 0.4;
408
+ else if (S < 3000) factor = 0.5;
409
+ else if (S < 10000) factor = 0.27;
410
+ else if (S < 30000) factor = 0.08;
411
+ else factor = 0.01;
412
+
413
+ int base = max(minW, (int)floor(sqrt((double)S * factor)));
414
+ vector<int> Ws;
415
+ {
416
+ unordered_set<int> used; used.reserve(512);
417
+ auto addW=[&](int w){if(w<minW) w=minW; if(used.insert(w).second) Ws.push_back(w);};
418
+ addW(base);
419
+ int span=min(96,max(20,base/2));
420
+ for(int d=1;d<=span;d++){addW(base-d); addW(base+d);}
421
+ addW(minW);
422
+ addW((int)max<long long>(minW,(S+base-1)/base));
423
+ for(int m=2;m<=6;m++){addW(base*m/3); addW((int)max<long long>(minW,S/((base*m/3)?(base*m/3):1)));}
424
+ // Add sqrt(S) based widths for more square-like rectangles
425
+ int sqrtS = max(minW, (int)floor(sqrt((double)S)));
426
+ addW(sqrtS);
427
+ addW(sqrtS+1);
428
+ addW(sqrtS-1);
429
+ addW(sqrtS*2/3);
430
+ addW(sqrtS/2);
431
+ sort(Ws.begin(),Ws.end(),[&](int a,int b){int da=abs(a-base),db=abs(b-base); if(da!=db) return da<db; return a<b;});
432
+ }
433
+ long long bestA=LLONG_MAX; int bestW=0,bestH=0; R bestR; bool hasBestmine=false;
434
+ auto t0=chrono::steady_clock::now();
435
+ const double TL=1980.0;
436
+ double avg=250.0; int cnt=0;
437
+
438
+ // Prepare orderings - fewer for gap packer (slower per call)
439
+ bool useGapPacker = (S < 12000);
440
+ vector<vector<int>> base_orders;
441
+ base_orders.push_back(ord_asc_mindim());
442
+ if(!useGapPacker){
443
+ base_orders.push_back(ord_desc_area());
444
+ base_orders.push_back(ord_desc_maxdim());
445
+ base_orders.push_back(ord_desc_bbox());
446
+ base_orders.push_back(ord_flexibility());
447
+ }
448
+ auto doPack = [&](int W, const vector<int>& order, RNG& rng, bool randtie) -> R {
449
+ if(useGapPacker) return pack_gap(W, order, rng, randtie);
450
+ return pack(W, order, rng, randtie);
451
+ };
452
+
453
+ // Track best ordering index per width for perturbation
454
+ int bestOrderIdx = 0;
455
+
456
+ for(int wi=0;wi<(int)Ws.size();wi++){
457
+ auto now=chrono::steady_clock::now();
458
+ double used_time=chrono::duration<double,milli>(now-t0).count();
459
+ if(used_time+avg*1.3>TL) break;
460
+ int W=Ws[wi];
461
+
462
+ // Try each base ordering
463
+ for(int oi=0;oi<(int)base_orders.size();oi++){
464
+ now=chrono::steady_clock::now();
465
+ double used2=chrono::duration<double,milli>(now-t0).count();
466
+ if(used2+avg*1.15>TL) break;
467
+ bool randtie=(oi>=1);
468
+ auto t1=chrono::steady_clock::now();
469
+ R r=doPack(W,base_orders[oi],rng,randtie);
470
+ auto t2=chrono::steady_clock::now();
471
+ double dt=chrono::duration<double,milli>(t2-t1).count();
472
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
473
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
474
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
475
+ bestOrderIdx=oi;
476
+ }
477
+ }
478
+
479
+ // Perturbation of best ordering + random orderings
480
+ int nswaps = max(1, n/20);
481
+ int maxRandom = useGapPacker ? 1 : 4;
482
+ for(int ri=0;ri<maxRandom;ri++){
483
+ now=chrono::steady_clock::now();
484
+ double used2=chrono::duration<double,milli>(now-t0).count();
485
+ if(used2+avg*1.15>TL) break;
486
+ auto t1=chrono::steady_clock::now();
487
+ vector<int> order;
488
+ if(ri < 2) order = ord_perturb(base_orders[bestOrderIdx], nswaps);
489
+ else order = ord_random();
490
+ R r=doPack(W,order,rng,true);
491
+ auto t2=chrono::steady_clock::now();
492
+ double dt=chrono::duration<double,milli>(t2-t1).count();
493
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
494
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
495
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
496
+ }
497
+ }
498
+ }
499
+ if(!hasBestmine){
500
+ int W=max(minW,(int)floor(sqrt((double)S)));
501
+ auto o=ord_asc_mindim();
502
+ R r=pack(W,o,rng,false);
503
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
504
+ }
505
+ int maxX=-1;
506
+ for(auto &p:bestR.pl){
507
+ auto &t=ps[p.idx].t[p.ti];
508
+ for(auto &q:t.c){int x=p.x+q.first; if(x>maxX) maxX=x;}
509
+ }
510
+ vector<int> mapx(maxX+1,-1);
511
+ if(maxX>=0){
512
+ vector<char> used(maxX+1,false);
513
+ for(auto &p:bestR.pl){
514
+ auto &t=ps[p.idx].t[p.ti];
515
+ for(auto &q:t.c){used[p.x+q.first]=true;}
516
+ }
517
+ int cur=0;
518
+ for(int x=0;x<=maxX;x++) if(used[x]) mapx[x]=cur++;
519
+ }
520
+ vector<array<int,4>> ans(n,{0,0,0,0});
521
+ for(auto &p:bestR.pl){
522
+ auto &t=ps[p.idx].t[p.ti];
523
+ int bx = (mapx.empty()?p.x:mapx[p.x]);
524
+ int Xi = bx - t.minx;
525
+ int Yi = p.y - t.miny;
526
+ int Ri = (4 - (t.r%4) + 4) % 4;
527
+ int Fi = t.f;
528
+ ans[p.idx]={Xi,Yi,Ri,Fi};
529
+ }
530
+ cout<<bestR.W<<" "<<bestR.H<<"\n";
531
+ for(int i=0;i<n;i++){
532
+ cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<"\n";
533
+ }
534
+ return 0;
535
+ }
docker_space/frontier_cs_0_polyomino_ev2/best/scores.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Best confirmed score: ~90.4 (varies 90.3-90.4 due to RNG)
2
+ Average ratio: 0.904
3
+ Min ratio: 0.873
4
+ Max ratio: 0.949
5
+
6
+ Improvement from baseline: 85.19 -> 90.4 (+5.2 points, +6.1%)
7
+
8
+ Key techniques:
9
+ 1. Multiple orderings (5 for skyline, 1 for gap packer) with perturbation restarts
10
+ 2. Waste-based between-piece scoring (dsum - k instead of dsum)
11
+ 3. Early lookahead boost (3x for first 10% of pieces)
12
+ 4. Gap-filling bitmap packer for S < 12000 (scans 3 rows below skyline)
13
+ 5. Adaptive time management with dynLIM for medium inputs
14
+ 6. 1 ordering + 1 random restart per width for gap packer (maximizes width diversity)
docker_space/frontier_cs_0_polyomino_ev2/examples/gpt5.cpp ADDED
@@ -0,0 +1,271 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <bits/stdc++.h>
2
+ using namespace std;
3
+
4
+ struct Cell { int x, y; };
5
+ struct Transform { int R, F; }; // reflect (y-axis) then rotate R*90° CW
6
+ struct Oriented {
7
+ vector<Cell> pts; // normalized: minx=miny=0
8
+ int w, h;
9
+ int offx, offy; // = -minx, -miny (to undo normalization for output)
10
+ Transform tf;
11
+ };
12
+ struct Piece {
13
+ int id;
14
+ vector<Cell> base;
15
+ vector<Oriented> variants;
16
+ int area;
17
+ };
18
+
19
+ static inline uint64_t pack_xy(int x,int y){
20
+ return (uint64_t(uint32_t(x))<<32) | uint32_t(y);
21
+ }
22
+ static inline pair<int,int> apply_transform(int x,int y,int F,int R){
23
+ if (F) x = -x;
24
+ switch (R & 3){
25
+ case 0: return { x, y};
26
+ case 1: return { y, -x}; // 90 CW
27
+ case 2: return {-x, -y}; // 180
28
+ default:return {-y, x}; // 270 CW
29
+ }
30
+ }
31
+ static Oriented make_oriented(const vector<Cell>& base,int F,int R){
32
+ vector<Cell> t; t.reserve(base.size());
33
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
34
+ for (auto &c: base){
35
+ auto [tx,ty]=apply_transform(c.x,c.y,F,R);
36
+ minx=min(minx,tx); miny=min(miny,ty);
37
+ maxx=max(maxx,tx); maxy=max(maxy,ty);
38
+ t.push_back({tx,ty});
39
+ }
40
+ // normalization
41
+ for (auto &c: t){ c.x -= minx; c.y -= miny; }
42
+ int W = maxx-minx+1, H = maxy-miny+1;
43
+ sort(t.begin(), t.end(), [](const Cell&a,const Cell&b){
44
+ if (a.y!=b.y) return a.y<b.y; return a.x<b.x;
45
+ });
46
+ return Oriented{t, W, H, -minx, -miny, Transform{R,F}};
47
+ }
48
+ static void build_variants(Piece& P){
49
+ vector<Oriented> cand; cand.reserve(8);
50
+ for (int F=0;F<=1;++F) for (int R=0;R<4;++R)
51
+ cand.push_back(make_oriented(P.base,F,R));
52
+ // dedup
53
+ vector<Oriented> uniq;
54
+ for (auto &o: cand){
55
+ bool dup=false;
56
+ for (auto &u: uniq){
57
+ if (u.w==o.w && u.h==o.h && u.pts.size()==o.pts.size()){
58
+ bool same=true;
59
+ for (size_t i=0;i<u.pts.size();++i)
60
+ if (u.pts[i].x!=o.pts[i].x || u.pts[i].y!=o.pts[i].y){ same=false; break; }
61
+ if (same){ dup=true; break; }
62
+ }
63
+ }
64
+ if (!dup) uniq.push_back(o);
65
+ }
66
+ P.variants.swap(uniq);
67
+ }
68
+
69
+ struct Placement { int X=0,Y=0,R=0,F=0; int w=0,h=0; int vi=-1; }; // vi = variant index used
70
+ struct PackedSolution { int W=0,H=0; vector<Placement> place; };
71
+
72
+ struct World {
73
+ int W, Hlimit; // square side S; W==Hlimit==S
74
+ vector<int> height;
75
+ unordered_set<uint64_t> occ;
76
+ int maxH=0;
77
+
78
+ World(int S=1){ clear(S); }
79
+ void clear(int S){ W=S; Hlimit=S; height.assign(W,0); occ.clear(); maxH=0; }
80
+
81
+ inline int shelfY(int x,int w) const {
82
+ int y=0; for (int i=0;i<w;++i) y=max(y,height[x+i]); return y;
83
+ }
84
+ inline bool can_place(const Oriented& o,int X,int Y) const {
85
+ if (X<0 || Y<0) return false;
86
+ if (X + o.w > W) return false;
87
+ if (Y + o.h > Hlimit) return false; // enforce square height cap
88
+ for (auto &c: o.pts){
89
+ int gx=X+c.x, gy=Y+c.y;
90
+ if (occ.find(pack_xy(gx,gy))!=occ.end()) return false;
91
+ }
92
+ return true;
93
+ }
94
+ inline void do_place(const Oriented& o,int X,int Y){
95
+ for (auto &c: o.pts){
96
+ int gx=X+c.x, gy=Y+c.y;
97
+ occ.insert(pack_xy(gx,gy));
98
+ height[gx]=max(height[gx], gy+1);
99
+ if (height[gx]>maxH) maxH=height[gx];
100
+ }
101
+ }
102
+ };
103
+
104
+ int main(){
105
+ ios::sync_with_stdio(false);
106
+ cin.tie(nullptr);
107
+
108
+ int n; if(!(cin>>n)) return 0;
109
+ vector<Piece> P(n);
110
+ long long totalCells=0;
111
+ for (int i=0;i<n;++i){
112
+ P[i].id=i;
113
+ int k; cin>>k;
114
+ P[i].base.resize(k);
115
+ for (int j=0;j<k;++j){ int x,y; cin>>x>>y; P[i].base[j]={x,y}; }
116
+ P[i].area=k; totalCells+=k;
117
+ build_variants(P[i]);
118
+ }
119
+
120
+ // Place larger / less flexible first
121
+ vector<int> order(n); iota(order.begin(), order.end(), 0);
122
+ sort(order.begin(), order.end(), [&](int a,int b){
123
+ if (P[a].area!=P[b].area) return P[a].area>P[b].area;
124
+ return P[a].variants.size()<P[b].variants.size();
125
+ });
126
+
127
+ // Lower bound on square side:
128
+ // 1) area bound
129
+ int S_area = (int)ceil(sqrt((long double)totalCells));
130
+ // 2) geometry bound: each piece needs some min side to fit; use min over variants of max(w,h)
131
+ int S_geom = 1;
132
+ for (auto &p: P){
133
+ int need = INT_MAX;
134
+ for (auto &o: p.variants) need = min(need, max(o.w, o.h));
135
+ S_geom = max(S_geom, need);
136
+ }
137
+ int S0 = max(S_area, S_geom);
138
+
139
+ // Generate candidate square sizes; grow if needed
140
+ vector<int> sides = {
141
+ S0,
142
+ max(S0, (int)ceil(1.05*S0)),
143
+ max(S0, (int)ceil(1.15*S0)),
144
+ max(S0, (int)ceil(0.95*S0))
145
+ };
146
+ sort(sides.begin(), sides.end());
147
+ sides.erase(unique(sides.begin(), sides.end()), sides.end());
148
+
149
+ auto better = [](const PackedSolution& A, const PackedSolution& B){
150
+ if (B.W==0) return true;
151
+ long long aA=1LL*A.W*A.H, aB=1LL*B.W*B.H;
152
+ if (aA!=aB) return aA<aB;
153
+ // If equal area (same S), prefer lower max column height (tie-breaker, though W=H).
154
+ if (A.H!=B.H) return A.H<B.H;
155
+ return A.W<B.W;
156
+ };
157
+
158
+ PackedSolution best; best.W=0; best.H=INT_MAX;
159
+
160
+ auto try_with_side = [&](int S)->optional<PackedSolution>{
161
+ World world(S);
162
+ world.occ.reserve((size_t)totalCells*2 + 1024);
163
+ vector<Placement> place(n);
164
+
165
+ for (int idx=0; idx<n; ++idx){
166
+ int i = order[idx];
167
+ auto &piece = P[i];
168
+
169
+ // Favor shorter/taller shapes appropriately
170
+ vector<int> vord(piece.variants.size());
171
+ iota(vord.begin(), vord.end(), 0);
172
+ sort(vord.begin(), vord.end(), [&](int a,int b){
173
+ const auto&A=piece.variants[a], &B=piece.variants[b];
174
+ if (A.h!=B.h) return A.h<B.h;
175
+ if (A.w!=B.w) return A.w>B.w;
176
+ return A.pts.size()>B.pts.size();
177
+ });
178
+
179
+ int bestVi=-1, bestX=-1, bestY=INT_MAX;
180
+
181
+ for (int vi: vord){
182
+ const auto &o = piece.variants[vi];
183
+ if (o.w > world.W || o.h > world.Hlimit) continue;
184
+
185
+ // x scan (try both coarse step and right align)
186
+ int step = max(1, o.w/2);
187
+ for (int x=0; x + o.w <= world.W; x += step){
188
+ int y = world.shelfY(x, o.w);
189
+ if (y + o.h > world.Hlimit) continue; // square cap
190
+ if (y > bestY) continue;
191
+ if (!world.can_place(o, x, y)) continue;
192
+ bestY=y; bestX=x; bestVi=vi;
193
+ }
194
+ int xr = world.W - o.w;
195
+ if (xr>=0){
196
+ int y = world.shelfY(xr, o.w);
197
+ if (y + o.h <= world.Hlimit && y <= bestY && world.can_place(o, xr, y)){
198
+ bestY=y; bestX=xr; bestVi=vi;
199
+ }
200
+ }
201
+ }
202
+
203
+ if (bestVi<0) return {}; // fail for this S
204
+
205
+ const auto &o = piece.variants[bestVi];
206
+ world.do_place(o, bestX, bestY);
207
+ place[i] = {bestX, bestY, o.tf.R, o.tf.F, o.w, o.h, bestVi};
208
+ }
209
+
210
+ // success with this S
211
+ PackedSolution cand;
212
+ cand.W = S;
213
+ cand.H = S; // enforce square
214
+ cand.place.resize(n);
215
+ for (int i=0;i<n;++i) cand.place[i]=place[i];
216
+ return cand;
217
+ };
218
+
219
+ // Try preset candidates
220
+ for (int S : sides){
221
+ if (auto sol = try_with_side(S)){
222
+ if (best.W==0 || better(*sol,best)) best=*sol;
223
+ }
224
+ }
225
+
226
+ // If none worked, escalate S until it does (guaranteed cap: vertical stack height)
227
+ if (best.W==0){
228
+ // Safe upper bound: stack piece heights of a chosen variant each
229
+ int maxW=1, sumH=0;
230
+ for (auto &p: P){
231
+ int wmin=INT_MAX, hmin=INT_MAX;
232
+ for (auto &o: p.variants){
233
+ wmin = min(wmin, o.w);
234
+ hmin = min(hmin, o.h);
235
+ }
236
+ maxW = max(maxW, wmin);
237
+ sumH += hmin;
238
+ }
239
+ int S = max({S0, maxW, sumH}); // square that trivially fits vertical stack
240
+ // grow linearly from S0 to S (usually hits long before)
241
+ for (int s = S0; s <= S; ++s){
242
+ if (auto sol = try_with_side(s)){ best = *sol; break; }
243
+ }
244
+ // If still nothing (extremely unlikely), force a trivial square stack at side S
245
+ if (best.W==0){
246
+ int y=0;
247
+ vector<Placement> pl(n);
248
+ // Use each piece's first variant
249
+ for (int i=0;i<n;++i){
250
+ const auto &o = P[i].variants[0];
251
+ pl[i]={0,y,o.tf.R,o.tf.F,o.w,o.h,0};
252
+ y += o.h;
253
+ }
254
+ int Sforce = max({S, y, maxW});
255
+ best.W = best.H = Sforce;
256
+ best.place = move(pl);
257
+ }
258
+ }
259
+
260
+ // ---- OUTPUT with offset compensation ----
261
+ cout << best.W << " " << best.H << "\n";
262
+ for (int i=0;i<n;++i){
263
+ const auto &pl = best.place[i];
264
+ const auto &o = P[i].variants[pl.vi];
265
+ // t = (X - minx, Y - miny) = (X + offx, Y + offy)
266
+ int Xout = pl.X + o.offx;
267
+ int Yout = pl.Y + o.offy;
268
+ cout << Xout << " " << Yout << " " << pl.R << " " << pl.F << "\n";
269
+ }
270
+ return 0;
271
+ }
docker_space/frontier_cs_0_polyomino_ev2/examples/reference.cpp ADDED
@@ -0,0 +1,297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ SOURCE: Shang Zhou
3
+ IIMOC SUBMISSION #1443
4
+ HUMAN BEST FOR POLYPACK (TRANSFORMATION OUTPUT FORMAT)
5
+ */
6
+
7
+ #include <bits/stdc++.h>
8
+ using namespace std;
9
+ struct T{int w,h;vector<pair<int,int>> c;vector<int> lo,hi;int r,f,minx,miny;};
10
+ struct P{int id,k;vector<pair<int,int>> b;vector<T> t;int minW=1e9,minH=1e9,minA=1e9;};
11
+ struct Pl{int idx,ti,x,y;};
12
+ struct R{long long A;int W,H;vector<Pl> pl;};
13
+ struct RNG{unsigned long long s;RNG(unsigned long long x){s=x?x:1;}inline unsigned long long nxt(){s^=s<<7;s^=s>>9;return s;}inline int rint(int n){return (int)(nxt()%n);}inline bool coin(){return nxt()&1;}};
14
+ static inline pair<int,int> rotp(pair<int,int> p,int r){if(r==0)return p; if(r==1)return make_pair(-p.second,p.first); if(r==2)return make_pair(-p.first,-p.second); return make_pair(p.second,-p.first);}
15
+ int main(){
16
+ ios::sync_with_stdio(false);
17
+ cin.tie(nullptr);
18
+ int n; if(!(cin>>n)) return 0;
19
+ vector<P> ps(n); long long S=0;
20
+ for(int i=0;i<n;i++){
21
+ int k;cin>>k; ps[i].id=i+1; ps[i].k=k; ps[i].b.resize(k);
22
+ for(int j=0;j<k;j++){int x,y;cin>>x>>y; ps[i].b[j]={x,y};}
23
+ S+=k;
24
+ }
25
+ for(int i=0;i<n;i++){
26
+ auto &p=ps[i]; unordered_set<string> seen; seen.reserve(32);
27
+ for(int rf=0;rf<2;rf++){
28
+ vector<pair<int,int>> src=p.b; if(rf){for(auto &q:src) q.first=-q.first;}
29
+ for(int r=0;r<4;r++){
30
+ vector<pair<int,int>> v=src; for(auto &q:v) q=rotp(q,r);
31
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
32
+ for(auto &q:v){minx=min(minx,q.first);miny=min(miny,q.second);maxx=max(maxx,q.first);maxy=max(maxy,q.second);}
33
+ vector<pair<int,int>> v2=v; for(auto &q:v2){q.first-=minx;q.second-=miny;}
34
+ sort(v2.begin(),v2.end());
35
+ string key; key.reserve(v2.size()*8);
36
+ for(auto &q:v2){key.append(to_string(q.first));key.push_back(',');key.append(to_string(q.second));key.push_back(';');}
37
+ if(seen.insert(key).second){
38
+ T t; t.w=maxx-minx+1; t.h=maxy-miny+1; t.c=v2; t.r=r; t.f=rf; t.minx=minx; t.miny=miny;
39
+ t.lo.assign(t.w,INT_MAX); t.hi.assign(t.w,INT_MIN);
40
+ for(auto &q:v2){int x=q.first,y=q.second; if(t.lo[x]>y) t.lo[x]=y; if(t.hi[x]<y) t.hi[x]=y;}
41
+ p.t.push_back(move(t));
42
+ }
43
+ }
44
+ }
45
+ for(auto &t:p.t){p.minW=min(p.minW,t.w); p.minH=min(p.minH,t.h); p.minA=min(p.minA,t.w*t.h);}
46
+ if(p.t.empty()){T t; t.w=1;t.h=1;t.c={{0,0}};t.lo={0};t.hi={0};t.r=0;t.f=0;t.minx=0;t.miny=0;p.t.push_back(t);p.minW=1;p.minH=1;p.minA=1;}
47
+ }
48
+ vector<int> idx(n); iota(idx.begin(),idx.end(),0);
49
+ unsigned long long seed=((unsigned long long)chrono::high_resolution_clock::now().time_since_epoch().count()) ^ (S<<1) ^ (unsigned long long)(n*1469598103934665603ULL);
50
+ RNG rng(seed);
51
+ auto ord4 = [&]() {
52
+ vector<int> res = idx;
53
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
54
+ int da = min(ps[a].minW, ps[a].minH);
55
+ int db = min(ps[b].minW, ps[b].minH);
56
+ if (da != db) return da < db;
57
+ if (ps[a].k != ps[b].k) return ps[a].k < ps[b].k;
58
+ return ps[a].id > ps[b].id;
59
+ });
60
+ return res;
61
+ };
62
+ auto pack=[&](int W,const vector<int>& o0,RNG &rng,bool randtie){
63
+ vector<int> h(W,-1);
64
+ long long g=-1;
65
+ vector<Pl> pl; pl.reserve(o0.size());
66
+ vector<int> o=o0;
67
+ int t=0,nm=(int)o.size();
68
+ bool big=S>7000;
69
+ int maxBound=max(1,n/4);
70
+ int expLIM=min(maxBound,(int)(350000/max(1LL,S-3500)));
71
+ int dynLIM=big?expLIM:maxBound;
72
+ auto tStart=chrono::steady_clock::now();
73
+ auto batchStart=tStart;
74
+ long long TLms=big?1900:LLONG_MAX/4;
75
+ int stepCnt=0;
76
+ while(t<nm){
77
+ int limCnt=max(1,dynLIM);
78
+ int lim=min(nm,t+limCnt);
79
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t; int bestid=-1;
80
+ for(int pos=t;pos<lim;pos++){
81
+ int id=o[pos];
82
+ auto &p=ps[id];
83
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
84
+ for(int ti=0;ti<(int)p.t.size();ti++){
85
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
86
+ for(int x0=0;x0<Rpos;x0++){
87
+ int y0=0;
88
+ for(int j=0;j<tsh.w;j++){
89
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
90
+ }
91
+ int nhbuf[32];
92
+ int l=-1; long long dsum=0;
93
+ for(int j=0;j<tsh.w;j++){
94
+ int nh=h[x0+j];
95
+ if(tsh.hi[j]!=INT_MIN){
96
+ int cand=y0+tsh.hi[j];
97
+ if(nh<cand) nh=cand;
98
+ }
99
+ nhbuf[j]=nh;
100
+ if(nh>l) l=nh;
101
+ }
102
+ for(int j=0;j<tsh.w;j++){
103
+ int inc=nhbuf[j]-h[x0+j];
104
+ if(inc>0) dsum+=inc;
105
+ }
106
+ long long dr=0;
107
+ if(x0>0){
108
+ long long old=llabs((long long)h[x0]-h[x0-1]);
109
+ long long nw=llabs((long long)nhbuf[0]-h[x0-1]);
110
+ dr+=nw-old;
111
+ }
112
+ for(int j=0;j<tsh.w-1;j++){
113
+ long long old=llabs((long long)h[x0+j+1]-h[x0+j]);
114
+ long long nw=llabs((long long)nhbuf[j+1]-nhbuf[j]);
115
+ dr+=nw-old;
116
+ }
117
+ if(x0+tsh.w<W){
118
+ long long old=llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);
119
+ long long nw=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1]);
120
+ dr+=nw-old;
121
+ }
122
+ long long gg=g; if(gg<l) gg=l;
123
+ bool take=false;
124
+ if(gg<bestg2) take=true;
125
+ else if(gg==bestg2){
126
+ if(dsum<bds2) take=true;
127
+ else if(dsum==bds2){
128
+ if(l<bl2) take=true;
129
+ else if(l==bl2){
130
+ if(dr<bdr2) take=true;
131
+ else if(dr==bdr2){
132
+ if(y0<by02) take=true;
133
+ else if(y0==by02){
134
+ if(x0<bx02) take=true;
135
+ else if(x0==bx02 && randtie && rng.coin()) take=true;
136
+ }
137
+ }
138
+ }
139
+ }
140
+ }
141
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=y0;bl2=l;bds2=dsum;bdr2=dr;by02=y0;bx02=x0;}
142
+ }
143
+ }
144
+ if(bti2==-1) continue;
145
+ bool take=false;
146
+ if(bestg2<bestg) take=true;
147
+ else if(bestg2==bestg){
148
+ if(bds2<bds) take=true;
149
+ else if(bds2==bds){
150
+ if(bl2<bl) take=true;
151
+ else if(bl2==bl){
152
+ if(bdr2<bdr) take=true;
153
+ else if(bdr2==bdr){
154
+ if(by02<by0) take=true;
155
+ else if(by02==by0){
156
+ if(bx02<bx0) take=true;
157
+ else if(bx02==bx0 && randtie && rng.coin()) take=true;
158
+ }
159
+ }
160
+ }
161
+ }
162
+ }
163
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=bds2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
164
+ }
165
+ if(bti==-1){t++;stepCnt++;if(big&&stepCnt==5){auto now=chrono::steady_clock::now(); auto elapsed=chrono::duration<double,milli>(now-tStart).count(); auto batch=chrono::duration<double,milli>(now-batchStart).count(); double remT=max(0.0,TLms-elapsed); int remSteps=max(1,nm-t); double budget=remT*5.0/remSteps; if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1); batchStart=now; stepCnt=0;} continue;}
166
+ auto &tsh=ps[bestid].t[bti];
167
+ for(int j=0;j<tsh.w;j++){
168
+ int nh=h[bx+j];
169
+ if(tsh.hi[j]!=INT_MIN){
170
+ int cand=by+tsh.hi[j];
171
+ if(nh<cand) nh=cand;
172
+ }
173
+ h[bx+j]=nh;
174
+ }
175
+ if(g<bl) g=bl;
176
+ pl.push_back({bestid,bti,bx,by});
177
+ if(bestpos!=t) swap(o[t],o[bestpos]);
178
+ t++;
179
+ stepCnt++;
180
+ if(big&&stepCnt==5){
181
+ auto now=chrono::steady_clock::now();
182
+ auto elapsed=chrono::duration<double,milli>(now-tStart).count();
183
+ auto batch=chrono::duration<double,milli>(now-batchStart).count();
184
+ double remT=max(0.0,TLms-elapsed);
185
+ int remSteps=max(1,nm-t);
186
+ double budget=remT*5.0/remSteps;
187
+ if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
188
+ batchStart=now;
189
+ stepCnt=0;
190
+ }
191
+ }
192
+ int H=(int)g+1;
193
+ int maxX=-1;
194
+ for(auto &pp:pl){
195
+ auto &t=ps[pp.idx].t[pp.ti];
196
+ for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}
197
+ }
198
+ int Wused=0;
199
+ if(maxX>=0){
200
+ vector<char> used(maxX+1,false);
201
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}}
202
+ for(int x=0;x<=maxX;x++) if(used[x]) Wused++;
203
+ }
204
+ int Wfinal=max(0,Wused);
205
+ long long A=1LL*H*max(1,Wfinal);
206
+ return R{A,max(1,Wfinal),H,move(pl)};
207
+ };
208
+ int minW=0; for(auto &p:ps) minW=max(minW,p.minW);
209
+ double factor;
210
+ if (S < 1000) {
211
+ factor = 0.4;
212
+ } else if (S < 3000) {
213
+ factor = 0.5;
214
+ } else if (S < 10000) {
215
+ factor = 0.27;
216
+ } else if (S < 30000) {
217
+ factor = 0.08;
218
+ } else {
219
+ factor = 0.01;
220
+ }
221
+ int base = max(minW, (int)floor(sqrt((double)S * factor)));
222
+ vector<int> Ws;
223
+ {
224
+ unordered_set<int> used; used.reserve(512);
225
+ auto addW=[&](int w){if(w<minW) w=minW; if(used.insert(w).second) Ws.push_back(w);};
226
+ addW(base);
227
+ int span=min(96,max(20,base/2));
228
+ for(int d=1;d<=span;d++){addW(base-d); addW(base+d);}
229
+ addW(minW);
230
+ addW((int)max<long long>(minW,(S+base-1)/base));
231
+ for(int m=2;m<=6;m++){addW(base*m/3); addW((int)max<long long>(minW,S/((base*m/3)?(base*m/3):1)));}
232
+ sort(Ws.begin(),Ws.end(),[&](int a,int b){int da=abs(a-base),db=abs(b-base); if(da!=db) return da<db; return a<b;});
233
+ }
234
+ long long bestA=LLONG_MAX; int bestW=0,bestH=0; R bestR; bool hasBestmine=false;
235
+ auto t0=chrono::steady_clock::now();
236
+ const double TL=1980.0;
237
+ double avg=250.0; int cnt=0;
238
+ for(int wi=0;wi<(int)Ws.size();wi++){
239
+ auto now=chrono::steady_clock::now();
240
+ double used=chrono::duration<double,milli>(now-t0).count();
241
+ if(used+avg*1.3>TL) break;
242
+ int W=Ws[wi];
243
+ vector<vector<int>> orders;
244
+ orders.push_back(ord4());
245
+ int oi=0;
246
+ while(oi<(int)orders.size()){
247
+ auto t1=chrono::steady_clock::now();
248
+ double used2=chrono::duration<double,milli>(t1-t0).count();
249
+ if(used2+avg*1.15>TL) break;
250
+ bool randtie=(oi>=1);
251
+ R r=pack(W,orders[oi],rng,randtie);
252
+ auto t2=chrono::steady_clock::now();
253
+ double dt=chrono::duration<double,milli>(t2-t1).count();
254
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
255
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
256
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
257
+ }
258
+ oi++;
259
+ }
260
+ }
261
+ if(!hasBestmine){
262
+ int W=max(minW,(int)floor(sqrt((double)S)));
263
+ auto o=ord4();
264
+ R r=pack(W,o,rng,false);
265
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
266
+ }
267
+ int maxX=-1;
268
+ for(auto &p:bestR.pl){
269
+ auto &t=ps[p.idx].t[p.ti];
270
+ for(auto &q:t.c){int x=p.x+q.first; if(x>maxX) maxX=x;}
271
+ }
272
+ vector<int> mapx(maxX+1,-1);
273
+ if(maxX>=0){
274
+ vector<char> used(maxX+1,false);
275
+ for(auto &p:bestR.pl){
276
+ auto &t=ps[p.idx].t[p.ti];
277
+ for(auto &q:t.c){used[p.x+q.first]=true;}
278
+ }
279
+ int cur=0;
280
+ for(int x=0;x<=maxX;x++) if(used[x]) mapx[x]=cur++;
281
+ }
282
+ vector<array<int,4>> ans(n,{0,0,0,0});
283
+ for(auto &p:bestR.pl){
284
+ auto &t=ps[p.idx].t[p.ti];
285
+ int bx = (mapx.empty()?p.x:mapx[p.x]);
286
+ int Xi = bx - t.minx;
287
+ int Yi = p.y - t.miny;
288
+ int Ri = (4 - (t.r%4) + 4) % 4;
289
+ int Fi = t.f;
290
+ ans[p.idx]={Xi,Yi,Ri,Fi};
291
+ }
292
+ cout<<bestR.W<<" "<<bestR.H<<"\n";
293
+ for(int i=0;i<n;i++){
294
+ cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<"\n";
295
+ }
296
+ return 0;
297
+ }
docker_space/frontier_cs_0_polyomino_ev2/logs/evolution.log ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Gen 0 | Score: 85.19 | Best: 85.19 | Status: baseline | Change: reference.cpp baseline
2
+ Gen 1 | Score: 88.77 | Best: 88.77 | Status: improved | Change: multiple orderings (desc area, desc maxdim, desc bbox, random) + sqrt(S) width candidates
3
+ Gen 2 | Score: 87.76 | Best: 88.77 | Status: reverted | Change: two-phase width search (worse - less time per width for ordering diversity)
4
+ Gen 3 | Score: 88.94 | Best: 88.94 | Status: improved | Change: added flexibility ordering + perturbation-based restarts
5
+ Gen 4 | Score: 64.01 | Best: 88.94 | Status: reverted | Change: multi-center width search (much worse - wide widths bad for skyline)
6
+ Gen 5 | Score: 89.63 | Best: 89.63 | Status: improved | Change: waste-based between-piece scoring (dsum-k) + early piece lookahead boost
7
+ Gen 6 | Score: 89.56 | Best: 89.63 | Status: reverted | Change: phase 3 random restarts on best width (slightly worse)
8
+ Gen 7 | Score: 89.59 | Best: 89.63 | Status: reverted | Change: variant pre-sorting (no improvement)
9
+ Gen 8 | Score: 89.61 | Best: 89.63 | Status: reverted | Change: early termination pruning (no improvement)
10
+ Gen 9 | Score: 89.58/89.57 | Best: 89.63 | Status: reverted | Change: Y-compaction post-processing (no improvement due to skyline already optimal locally)
11
+ Gen 10 | Score: 89.25 | Best: 89.63 | Status: reverted | Change: bitmap-based exact packer for small inputs (too slow, fewer trials)
12
+ Gen 11 | Score: 89.61 | Best: 89.63 | Status: reverted | Change: skyline-based early cutoff (negligible effect)
13
+ Gen 12 | Score: 89.53 | Best: 89.63 | Status: reverted | Change: added compact+interleaved orderings (too many orderings, fewer widths)
14
+ Gen 13 | Score: 89.63 | Best: 89.63 | Status: tie | Change: 3 orderings + 6 restarts (no improvement over 5+4)
15
+ Gen 14 | Score: 85.56 | Best: 89.63 | Status: reverted | Change: top-piece re-packing with exact tracking (TLE on most cases)
16
+ Gen 15 | Score: 89.46 | Best: 89.63 | Status: reverted | Change: more aggressive early boost (too much time consumed)
17
+ Gen 16 | Score: 89.21 | Best: 89.63 | Status: reverted | Change: composite scoring (hierarchical is better)
18
+ Gen 17 | Score: 89.56 | Best: 89.63 | Status: reverted | Change: adaptive orderings per width size (no improvement)
19
+ Gen 18 | Score: 90.00 | Best: 90.00 | Status: improved | Change: gap-filling pack_gap with bitmap for S<2000, scan depth 3
20
+ Gen 19 | Score: 89.93 | Best: 90.00 | Status: reverted | Change: threshold 1500 (worse)
21
+ Gen 20 | Score: 90.06 | Best: 90.06 | Status: improved | Change: threshold 2500 for gap packer
22
+ Gen 21 | Score: 90.04 | Best: 90.06 | Status: reverted | Change: threshold 3500 (slightly worse)
23
+ Gen 22 | Score: 90.00 | Best: 90.06 | Status: reverted | Change: scan depth 5 (slightly worse)
24
+ Gen 23 | Score: 89.99 | Best: 90.06 | Status: reverted | Change: time-aware gap control (too aggressive cutoff)
25
+ Gen 24-25 | Score: 89.99-90.02 | Best: 90.06 | Status: noise | Change: adaptive scan depth (within noise)
26
+ Gen 26 | Score: 90.13 | Best: 90.13 | Status: improved | Change: 3 orderings for gap packer (more widths explored)
27
+ Gen 27 | Score: 90.22 | Best: 90.22 | Status: improved | Change: only 2 orderings + 2 random for gap packer
28
+ Gen 28 | Score: 90.27 | Best: 90.27 | Status: improved | Change: 1 ordering + 1 random for gap packer (max width diversity)
29
+ Gen 29 | Score: 87.60 | Best: 90.27 | Status: reverted | Change: 0 random restarts (too few trials)
30
+ Gen 30 | Score: 90.32 | Best: 90.32 | Status: improved | Change: gap packer threshold S<5000
31
+ Gen 31 | Score: 90.33 | Best: 90.33 | Status: improved | Change: gap packer threshold S<8000
32
+ Gen 32 | Score: 82.20 | Best: 90.33 | Status: reverted | Change: threshold 15000 (too slow for medium cases)
33
+ Gen 33 | Score: 90.42 | Best: 90.42 | Status: improved | Change: gap packer with adaptive time management, S<12000 threshold
34
+ Gen 34 | Score: 90.29 | Best: 90.42 | Status: reverted | Change: threshold 25000 (slightly worse)
35
+ Gen 35 | Score: 88.98 | Best: 90.42 | Status: reverted | Change: scan depth 5 (too slow with time mgmt)
36
+ Gen 36 | Score: 89.06 | Best: 90.42 | Status: reverted | Change: adaptive depth + threshold 20000 (too slow)
37
+ Gen 37 | Score: 88.90 | Best: 90.42 | Status: reverted | Change: 2 orderings for gap (worse, less width diversity)
38
+ Gen 38 | Score: 90.34 | Best: 90.42 | Status: reverted | Change: reduced orderings for large too (worse)
39
+
40
+ === Final Summary ===
41
+ Best confirmed score: ~90.4 (avg ratio 0.904)
42
+ Improvement: 85.19 → 90.4 (+5.2 points, +6.1%)
43
+
44
+ Key improvements:
45
+ 1. Multiple orderings: +3.6 points
46
+ 2. Waste-based scoring + early boost: +0.7 points
47
+ 3. Gap-filling bitmap packer: +0.8 points
48
+ 4. Adaptive time management for gap packer: +0.1 points
docker_space/frontier_cs_0_polyomino_ev2/logs/gen_0.cpp ADDED
@@ -0,0 +1,297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ SOURCE: Shang Zhou
3
+ IIMOC SUBMISSION #1443
4
+ HUMAN BEST FOR POLYPACK (TRANSFORMATION OUTPUT FORMAT)
5
+ */
6
+
7
+ #include <bits/stdc++.h>
8
+ using namespace std;
9
+ struct T{int w,h;vector<pair<int,int>> c;vector<int> lo,hi;int r,f,minx,miny;};
10
+ struct P{int id,k;vector<pair<int,int>> b;vector<T> t;int minW=1e9,minH=1e9,minA=1e9;};
11
+ struct Pl{int idx,ti,x,y;};
12
+ struct R{long long A;int W,H;vector<Pl> pl;};
13
+ struct RNG{unsigned long long s;RNG(unsigned long long x){s=x?x:1;}inline unsigned long long nxt(){s^=s<<7;s^=s>>9;return s;}inline int rint(int n){return (int)(nxt()%n);}inline bool coin(){return nxt()&1;}};
14
+ static inline pair<int,int> rotp(pair<int,int> p,int r){if(r==0)return p; if(r==1)return make_pair(-p.second,p.first); if(r==2)return make_pair(-p.first,-p.second); return make_pair(p.second,-p.first);}
15
+ int main(){
16
+ ios::sync_with_stdio(false);
17
+ cin.tie(nullptr);
18
+ int n; if(!(cin>>n)) return 0;
19
+ vector<P> ps(n); long long S=0;
20
+ for(int i=0;i<n;i++){
21
+ int k;cin>>k; ps[i].id=i+1; ps[i].k=k; ps[i].b.resize(k);
22
+ for(int j=0;j<k;j++){int x,y;cin>>x>>y; ps[i].b[j]={x,y};}
23
+ S+=k;
24
+ }
25
+ for(int i=0;i<n;i++){
26
+ auto &p=ps[i]; unordered_set<string> seen; seen.reserve(32);
27
+ for(int rf=0;rf<2;rf++){
28
+ vector<pair<int,int>> src=p.b; if(rf){for(auto &q:src) q.first=-q.first;}
29
+ for(int r=0;r<4;r++){
30
+ vector<pair<int,int>> v=src; for(auto &q:v) q=rotp(q,r);
31
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
32
+ for(auto &q:v){minx=min(minx,q.first);miny=min(miny,q.second);maxx=max(maxx,q.first);maxy=max(maxy,q.second);}
33
+ vector<pair<int,int>> v2=v; for(auto &q:v2){q.first-=minx;q.second-=miny;}
34
+ sort(v2.begin(),v2.end());
35
+ string key; key.reserve(v2.size()*8);
36
+ for(auto &q:v2){key.append(to_string(q.first));key.push_back(',');key.append(to_string(q.second));key.push_back(';');}
37
+ if(seen.insert(key).second){
38
+ T t; t.w=maxx-minx+1; t.h=maxy-miny+1; t.c=v2; t.r=r; t.f=rf; t.minx=minx; t.miny=miny;
39
+ t.lo.assign(t.w,INT_MAX); t.hi.assign(t.w,INT_MIN);
40
+ for(auto &q:v2){int x=q.first,y=q.second; if(t.lo[x]>y) t.lo[x]=y; if(t.hi[x]<y) t.hi[x]=y;}
41
+ p.t.push_back(move(t));
42
+ }
43
+ }
44
+ }
45
+ for(auto &t:p.t){p.minW=min(p.minW,t.w); p.minH=min(p.minH,t.h); p.minA=min(p.minA,t.w*t.h);}
46
+ if(p.t.empty()){T t; t.w=1;t.h=1;t.c={{0,0}};t.lo={0};t.hi={0};t.r=0;t.f=0;t.minx=0;t.miny=0;p.t.push_back(t);p.minW=1;p.minH=1;p.minA=1;}
47
+ }
48
+ vector<int> idx(n); iota(idx.begin(),idx.end(),0);
49
+ unsigned long long seed=((unsigned long long)chrono::high_resolution_clock::now().time_since_epoch().count()) ^ (S<<1) ^ (unsigned long long)(n*1469598103934665603ULL);
50
+ RNG rng(seed);
51
+ auto ord4 = [&]() {
52
+ vector<int> res = idx;
53
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
54
+ int da = min(ps[a].minW, ps[a].minH);
55
+ int db = min(ps[b].minW, ps[b].minH);
56
+ if (da != db) return da < db;
57
+ if (ps[a].k != ps[b].k) return ps[a].k < ps[b].k;
58
+ return ps[a].id > ps[b].id;
59
+ });
60
+ return res;
61
+ };
62
+ auto pack=[&](int W,const vector<int>& o0,RNG &rng,bool randtie){
63
+ vector<int> h(W,-1);
64
+ long long g=-1;
65
+ vector<Pl> pl; pl.reserve(o0.size());
66
+ vector<int> o=o0;
67
+ int t=0,nm=(int)o.size();
68
+ bool big=S>7000;
69
+ int maxBound=max(1,n/4);
70
+ int expLIM=min(maxBound,(int)(350000/max(1LL,S-3500)));
71
+ int dynLIM=big?expLIM:maxBound;
72
+ auto tStart=chrono::steady_clock::now();
73
+ auto batchStart=tStart;
74
+ long long TLms=big?1900:LLONG_MAX/4;
75
+ int stepCnt=0;
76
+ while(t<nm){
77
+ int limCnt=max(1,dynLIM);
78
+ int lim=min(nm,t+limCnt);
79
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t; int bestid=-1;
80
+ for(int pos=t;pos<lim;pos++){
81
+ int id=o[pos];
82
+ auto &p=ps[id];
83
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
84
+ for(int ti=0;ti<(int)p.t.size();ti++){
85
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
86
+ for(int x0=0;x0<Rpos;x0++){
87
+ int y0=0;
88
+ for(int j=0;j<tsh.w;j++){
89
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
90
+ }
91
+ int nhbuf[32];
92
+ int l=-1; long long dsum=0;
93
+ for(int j=0;j<tsh.w;j++){
94
+ int nh=h[x0+j];
95
+ if(tsh.hi[j]!=INT_MIN){
96
+ int cand=y0+tsh.hi[j];
97
+ if(nh<cand) nh=cand;
98
+ }
99
+ nhbuf[j]=nh;
100
+ if(nh>l) l=nh;
101
+ }
102
+ for(int j=0;j<tsh.w;j++){
103
+ int inc=nhbuf[j]-h[x0+j];
104
+ if(inc>0) dsum+=inc;
105
+ }
106
+ long long dr=0;
107
+ if(x0>0){
108
+ long long old=llabs((long long)h[x0]-h[x0-1]);
109
+ long long nw=llabs((long long)nhbuf[0]-h[x0-1]);
110
+ dr+=nw-old;
111
+ }
112
+ for(int j=0;j<tsh.w-1;j++){
113
+ long long old=llabs((long long)h[x0+j+1]-h[x0+j]);
114
+ long long nw=llabs((long long)nhbuf[j+1]-nhbuf[j]);
115
+ dr+=nw-old;
116
+ }
117
+ if(x0+tsh.w<W){
118
+ long long old=llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);
119
+ long long nw=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1]);
120
+ dr+=nw-old;
121
+ }
122
+ long long gg=g; if(gg<l) gg=l;
123
+ bool take=false;
124
+ if(gg<bestg2) take=true;
125
+ else if(gg==bestg2){
126
+ if(dsum<bds2) take=true;
127
+ else if(dsum==bds2){
128
+ if(l<bl2) take=true;
129
+ else if(l==bl2){
130
+ if(dr<bdr2) take=true;
131
+ else if(dr==bdr2){
132
+ if(y0<by02) take=true;
133
+ else if(y0==by02){
134
+ if(x0<bx02) take=true;
135
+ else if(x0==bx02 && randtie && rng.coin()) take=true;
136
+ }
137
+ }
138
+ }
139
+ }
140
+ }
141
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=y0;bl2=l;bds2=dsum;bdr2=dr;by02=y0;bx02=x0;}
142
+ }
143
+ }
144
+ if(bti2==-1) continue;
145
+ bool take=false;
146
+ if(bestg2<bestg) take=true;
147
+ else if(bestg2==bestg){
148
+ if(bds2<bds) take=true;
149
+ else if(bds2==bds){
150
+ if(bl2<bl) take=true;
151
+ else if(bl2==bl){
152
+ if(bdr2<bdr) take=true;
153
+ else if(bdr2==bdr){
154
+ if(by02<by0) take=true;
155
+ else if(by02==by0){
156
+ if(bx02<bx0) take=true;
157
+ else if(bx02==bx0 && randtie && rng.coin()) take=true;
158
+ }
159
+ }
160
+ }
161
+ }
162
+ }
163
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=bds2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
164
+ }
165
+ if(bti==-1){t++;stepCnt++;if(big&&stepCnt==5){auto now=chrono::steady_clock::now(); auto elapsed=chrono::duration<double,milli>(now-tStart).count(); auto batch=chrono::duration<double,milli>(now-batchStart).count(); double remT=max(0.0,TLms-elapsed); int remSteps=max(1,nm-t); double budget=remT*5.0/remSteps; if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1); batchStart=now; stepCnt=0;} continue;}
166
+ auto &tsh=ps[bestid].t[bti];
167
+ for(int j=0;j<tsh.w;j++){
168
+ int nh=h[bx+j];
169
+ if(tsh.hi[j]!=INT_MIN){
170
+ int cand=by+tsh.hi[j];
171
+ if(nh<cand) nh=cand;
172
+ }
173
+ h[bx+j]=nh;
174
+ }
175
+ if(g<bl) g=bl;
176
+ pl.push_back({bestid,bti,bx,by});
177
+ if(bestpos!=t) swap(o[t],o[bestpos]);
178
+ t++;
179
+ stepCnt++;
180
+ if(big&&stepCnt==5){
181
+ auto now=chrono::steady_clock::now();
182
+ auto elapsed=chrono::duration<double,milli>(now-tStart).count();
183
+ auto batch=chrono::duration<double,milli>(now-batchStart).count();
184
+ double remT=max(0.0,TLms-elapsed);
185
+ int remSteps=max(1,nm-t);
186
+ double budget=remT*5.0/remSteps;
187
+ if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
188
+ batchStart=now;
189
+ stepCnt=0;
190
+ }
191
+ }
192
+ int H=(int)g+1;
193
+ int maxX=-1;
194
+ for(auto &pp:pl){
195
+ auto &t=ps[pp.idx].t[pp.ti];
196
+ for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}
197
+ }
198
+ int Wused=0;
199
+ if(maxX>=0){
200
+ vector<char> used(maxX+1,false);
201
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}}
202
+ for(int x=0;x<=maxX;x++) if(used[x]) Wused++;
203
+ }
204
+ int Wfinal=max(0,Wused);
205
+ long long A=1LL*H*max(1,Wfinal);
206
+ return R{A,max(1,Wfinal),H,move(pl)};
207
+ };
208
+ int minW=0; for(auto &p:ps) minW=max(minW,p.minW);
209
+ double factor;
210
+ if (S < 1000) {
211
+ factor = 0.4;
212
+ } else if (S < 3000) {
213
+ factor = 0.5;
214
+ } else if (S < 10000) {
215
+ factor = 0.27;
216
+ } else if (S < 30000) {
217
+ factor = 0.08;
218
+ } else {
219
+ factor = 0.01;
220
+ }
221
+ int base = max(minW, (int)floor(sqrt((double)S * factor)));
222
+ vector<int> Ws;
223
+ {
224
+ unordered_set<int> used; used.reserve(512);
225
+ auto addW=[&](int w){if(w<minW) w=minW; if(used.insert(w).second) Ws.push_back(w);};
226
+ addW(base);
227
+ int span=min(96,max(20,base/2));
228
+ for(int d=1;d<=span;d++){addW(base-d); addW(base+d);}
229
+ addW(minW);
230
+ addW((int)max<long long>(minW,(S+base-1)/base));
231
+ for(int m=2;m<=6;m++){addW(base*m/3); addW((int)max<long long>(minW,S/((base*m/3)?(base*m/3):1)));}
232
+ sort(Ws.begin(),Ws.end(),[&](int a,int b){int da=abs(a-base),db=abs(b-base); if(da!=db) return da<db; return a<b;});
233
+ }
234
+ long long bestA=LLONG_MAX; int bestW=0,bestH=0; R bestR; bool hasBestmine=false;
235
+ auto t0=chrono::steady_clock::now();
236
+ const double TL=1980.0;
237
+ double avg=250.0; int cnt=0;
238
+ for(int wi=0;wi<(int)Ws.size();wi++){
239
+ auto now=chrono::steady_clock::now();
240
+ double used=chrono::duration<double,milli>(now-t0).count();
241
+ if(used+avg*1.3>TL) break;
242
+ int W=Ws[wi];
243
+ vector<vector<int>> orders;
244
+ orders.push_back(ord4());
245
+ int oi=0;
246
+ while(oi<(int)orders.size()){
247
+ auto t1=chrono::steady_clock::now();
248
+ double used2=chrono::duration<double,milli>(t1-t0).count();
249
+ if(used2+avg*1.15>TL) break;
250
+ bool randtie=(oi>=1);
251
+ R r=pack(W,orders[oi],rng,randtie);
252
+ auto t2=chrono::steady_clock::now();
253
+ double dt=chrono::duration<double,milli>(t2-t1).count();
254
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
255
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
256
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
257
+ }
258
+ oi++;
259
+ }
260
+ }
261
+ if(!hasBestmine){
262
+ int W=max(minW,(int)floor(sqrt((double)S)));
263
+ auto o=ord4();
264
+ R r=pack(W,o,rng,false);
265
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
266
+ }
267
+ int maxX=-1;
268
+ for(auto &p:bestR.pl){
269
+ auto &t=ps[p.idx].t[p.ti];
270
+ for(auto &q:t.c){int x=p.x+q.first; if(x>maxX) maxX=x;}
271
+ }
272
+ vector<int> mapx(maxX+1,-1);
273
+ if(maxX>=0){
274
+ vector<char> used(maxX+1,false);
275
+ for(auto &p:bestR.pl){
276
+ auto &t=ps[p.idx].t[p.ti];
277
+ for(auto &q:t.c){used[p.x+q.first]=true;}
278
+ }
279
+ int cur=0;
280
+ for(int x=0;x<=maxX;x++) if(used[x]) mapx[x]=cur++;
281
+ }
282
+ vector<array<int,4>> ans(n,{0,0,0,0});
283
+ for(auto &p:bestR.pl){
284
+ auto &t=ps[p.idx].t[p.ti];
285
+ int bx = (mapx.empty()?p.x:mapx[p.x]);
286
+ int Xi = bx - t.minx;
287
+ int Yi = p.y - t.miny;
288
+ int Ri = (4 - (t.r%4) + 4) % 4;
289
+ int Fi = t.f;
290
+ ans[p.idx]={Xi,Yi,Ri,Fi};
291
+ }
292
+ cout<<bestR.W<<" "<<bestR.H<<"\n";
293
+ for(int i=0;i<n;i++){
294
+ cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<"\n";
295
+ }
296
+ return 0;
297
+ }
docker_space/frontier_cs_0_polyomino_ev2/logs/gen_1.cpp ADDED
@@ -0,0 +1,366 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Gen 1: Multiple orderings + improved width search
3
+ Based on reference.cpp with:
4
+ - 4 ordering strategies (ascending min dim, descending area, descending max dim, random)
5
+ - Each width tries all orderings (time permitting)
6
+ - Better width candidate generation
7
+ */
8
+ #include <bits/stdc++.h>
9
+ using namespace std;
10
+ struct T{int w,h;vector<pair<int,int>> c;vector<int> lo,hi;int r,f,minx,miny;};
11
+ struct P{int id,k;vector<pair<int,int>> b;vector<T> t;int minW=1e9,minH=1e9,minA=1e9;};
12
+ struct Pl{int idx,ti,x,y;};
13
+ struct R{long long A;int W,H;vector<Pl> pl;};
14
+ struct RNG{unsigned long long s;RNG(unsigned long long x){s=x?x:1;}inline unsigned long long nxt(){s^=s<<7;s^=s>>9;return s;}inline int rint(int n){return (int)(nxt()%n);}inline bool coin(){return nxt()&1;}};
15
+ static inline pair<int,int> rotp(pair<int,int> p,int r){if(r==0)return p; if(r==1)return make_pair(-p.second,p.first); if(r==2)return make_pair(-p.first,-p.second); return make_pair(p.second,-p.first);}
16
+ int main(){
17
+ ios::sync_with_stdio(false);
18
+ cin.tie(nullptr);
19
+ int n; if(!(cin>>n)) return 0;
20
+ vector<P> ps(n); long long S=0;
21
+ for(int i=0;i<n;i++){
22
+ int k;cin>>k; ps[i].id=i+1; ps[i].k=k; ps[i].b.resize(k);
23
+ for(int j=0;j<k;j++){int x,y;cin>>x>>y; ps[i].b[j]={x,y};}
24
+ S+=k;
25
+ }
26
+ for(int i=0;i<n;i++){
27
+ auto &p=ps[i]; unordered_set<string> seen; seen.reserve(32);
28
+ for(int rf=0;rf<2;rf++){
29
+ vector<pair<int,int>> src=p.b; if(rf){for(auto &q:src) q.first=-q.first;}
30
+ for(int r=0;r<4;r++){
31
+ vector<pair<int,int>> v=src; for(auto &q:v) q=rotp(q,r);
32
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
33
+ for(auto &q:v){minx=min(minx,q.first);miny=min(miny,q.second);maxx=max(maxx,q.first);maxy=max(maxy,q.second);}
34
+ vector<pair<int,int>> v2=v; for(auto &q:v2){q.first-=minx;q.second-=miny;}
35
+ sort(v2.begin(),v2.end());
36
+ string key; key.reserve(v2.size()*8);
37
+ for(auto &q:v2){key.append(to_string(q.first));key.push_back(',');key.append(to_string(q.second));key.push_back(';');}
38
+ if(seen.insert(key).second){
39
+ T t; t.w=maxx-minx+1; t.h=maxy-miny+1; t.c=v2; t.r=r; t.f=rf; t.minx=minx; t.miny=miny;
40
+ t.lo.assign(t.w,INT_MAX); t.hi.assign(t.w,INT_MIN);
41
+ for(auto &q:v2){int x=q.first,y=q.second; if(t.lo[x]>y) t.lo[x]=y; if(t.hi[x]<y) t.hi[x]=y;}
42
+ p.t.push_back(move(t));
43
+ }
44
+ }
45
+ }
46
+ for(auto &t:p.t){p.minW=min(p.minW,t.w); p.minH=min(p.minH,t.h); p.minA=min(p.minA,t.w*t.h);}
47
+ if(p.t.empty()){T t; t.w=1;t.h=1;t.c={{0,0}};t.lo={0};t.hi={0};t.r=0;t.f=0;t.minx=0;t.miny=0;p.t.push_back(t);p.minW=1;p.minH=1;p.minA=1;}
48
+ }
49
+ vector<int> idx(n); iota(idx.begin(),idx.end(),0);
50
+ unsigned long long seed=((unsigned long long)chrono::high_resolution_clock::now().time_since_epoch().count()) ^ (S<<1) ^ (unsigned long long)(n*1469598103934665603ULL);
51
+ RNG rng(seed);
52
+
53
+ // Multiple ordering strategies
54
+ auto ord_asc_mindim = [&]() {
55
+ vector<int> res = idx;
56
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
57
+ int da = min(ps[a].minW, ps[a].minH);
58
+ int db = min(ps[b].minW, ps[b].minH);
59
+ if (da != db) return da < db;
60
+ if (ps[a].k != ps[b].k) return ps[a].k < ps[b].k;
61
+ return ps[a].id > ps[b].id;
62
+ });
63
+ return res;
64
+ };
65
+ auto ord_desc_area = [&]() {
66
+ vector<int> res = idx;
67
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
68
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
69
+ int da = min(ps[a].minW, ps[a].minH);
70
+ int db = min(ps[b].minW, ps[b].minH);
71
+ if (da != db) return da > db;
72
+ return ps[a].id < ps[b].id;
73
+ });
74
+ return res;
75
+ };
76
+ auto ord_desc_maxdim = [&]() {
77
+ vector<int> res = idx;
78
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
79
+ int da = max(ps[a].minW, ps[a].minH);
80
+ int db = max(ps[b].minW, ps[b].minH);
81
+ if (da != db) return da > db;
82
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
83
+ return ps[a].id < ps[b].id;
84
+ });
85
+ return res;
86
+ };
87
+ auto ord_desc_bbox = [&]() {
88
+ vector<int> res = idx;
89
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
90
+ if (ps[a].minA != ps[b].minA) return ps[a].minA > ps[b].minA;
91
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
92
+ return ps[a].id < ps[b].id;
93
+ });
94
+ return res;
95
+ };
96
+ auto ord_random = [&]() {
97
+ vector<int> res = idx;
98
+ for(int i=n-1;i>0;i--){
99
+ int j=rng.rint(i+1);
100
+ swap(res[i],res[j]);
101
+ }
102
+ return res;
103
+ };
104
+
105
+ auto pack=[&](int W,const vector<int>& o0,RNG &rng,bool randtie){
106
+ vector<int> h(W,-1);
107
+ long long g=-1;
108
+ vector<Pl> pl; pl.reserve(o0.size());
109
+ vector<int> o=o0;
110
+ int t=0,nm=(int)o.size();
111
+ bool big=S>7000;
112
+ int maxBound=max(1,n/4);
113
+ int expLIM=min(maxBound,(int)(350000/max(1LL,S-3500)));
114
+ int dynLIM=big?expLIM:maxBound;
115
+ auto tStart=chrono::steady_clock::now();
116
+ auto batchStart=tStart;
117
+ long long TLms=big?1900:LLONG_MAX/4;
118
+ int stepCnt=0;
119
+ while(t<nm){
120
+ int limCnt=max(1,dynLIM);
121
+ int lim=min(nm,t+limCnt);
122
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t; int bestid=-1;
123
+ for(int pos=t;pos<lim;pos++){
124
+ int id=o[pos];
125
+ auto &p=ps[id];
126
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
127
+ for(int ti=0;ti<(int)p.t.size();ti++){
128
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
129
+ for(int x0=0;x0<Rpos;x0++){
130
+ int y0=0;
131
+ for(int j=0;j<tsh.w;j++){
132
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
133
+ }
134
+ int nhbuf[32];
135
+ int l=-1; long long dsum=0;
136
+ for(int j=0;j<tsh.w;j++){
137
+ int nh=h[x0+j];
138
+ if(tsh.hi[j]!=INT_MIN){
139
+ int cand=y0+tsh.hi[j];
140
+ if(nh<cand) nh=cand;
141
+ }
142
+ nhbuf[j]=nh;
143
+ if(nh>l) l=nh;
144
+ }
145
+ for(int j=0;j<tsh.w;j++){
146
+ int inc=nhbuf[j]-h[x0+j];
147
+ if(inc>0) dsum+=inc;
148
+ }
149
+ long long dr=0;
150
+ if(x0>0){
151
+ long long old=llabs((long long)h[x0]-h[x0-1]);
152
+ long long nw=llabs((long long)nhbuf[0]-h[x0-1]);
153
+ dr+=nw-old;
154
+ }
155
+ for(int j=0;j<tsh.w-1;j++){
156
+ long long old=llabs((long long)h[x0+j+1]-h[x0+j]);
157
+ long long nw=llabs((long long)nhbuf[j+1]-nhbuf[j]);
158
+ dr+=nw-old;
159
+ }
160
+ if(x0+tsh.w<W){
161
+ long long old=llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);
162
+ long long nw=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1]);
163
+ dr+=nw-old;
164
+ }
165
+ long long gg=g; if(gg<l) gg=l;
166
+ bool take=false;
167
+ if(gg<bestg2) take=true;
168
+ else if(gg==bestg2){
169
+ if(dsum<bds2) take=true;
170
+ else if(dsum==bds2){
171
+ if(l<bl2) take=true;
172
+ else if(l==bl2){
173
+ if(dr<bdr2) take=true;
174
+ else if(dr==bdr2){
175
+ if(y0<by02) take=true;
176
+ else if(y0==by02){
177
+ if(x0<bx02) take=true;
178
+ else if(x0==bx02 && randtie && rng.coin()) take=true;
179
+ }
180
+ }
181
+ }
182
+ }
183
+ }
184
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=y0;bl2=l;bds2=dsum;bdr2=dr;by02=y0;bx02=x0;}
185
+ }
186
+ }
187
+ if(bti2==-1) continue;
188
+ bool take=false;
189
+ if(bestg2<bestg) take=true;
190
+ else if(bestg2==bestg){
191
+ if(bds2<bds) take=true;
192
+ else if(bds2==bds){
193
+ if(bl2<bl) take=true;
194
+ else if(bl2==bl){
195
+ if(bdr2<bdr) take=true;
196
+ else if(bdr2==bdr){
197
+ if(by02<by0) take=true;
198
+ else if(by02==by0){
199
+ if(bx02<bx0) take=true;
200
+ else if(bx02==bx0 && randtie && rng.coin()) take=true;
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
206
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=bds2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
207
+ }
208
+ if(bti==-1){t++;stepCnt++;if(big&&stepCnt==5){auto now=chrono::steady_clock::now(); auto elapsed=chrono::duration<double,milli>(now-tStart).count(); auto batch=chrono::duration<double,milli>(now-batchStart).count(); double remT=max(0.0,TLms-elapsed); int remSteps=max(1,nm-t); double budget=remT*5.0/remSteps; if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1); batchStart=now; stepCnt=0;} continue;}
209
+ auto &tsh=ps[bestid].t[bti];
210
+ for(int j=0;j<tsh.w;j++){
211
+ int nh=h[bx+j];
212
+ if(tsh.hi[j]!=INT_MIN){
213
+ int cand=by+tsh.hi[j];
214
+ if(nh<cand) nh=cand;
215
+ }
216
+ h[bx+j]=nh;
217
+ }
218
+ if(g<bl) g=bl;
219
+ pl.push_back({bestid,bti,bx,by});
220
+ if(bestpos!=t) swap(o[t],o[bestpos]);
221
+ t++;
222
+ stepCnt++;
223
+ if(big&&stepCnt==5){
224
+ auto now=chrono::steady_clock::now();
225
+ auto elapsed=chrono::duration<double,milli>(now-tStart).count();
226
+ auto batch=chrono::duration<double,milli>(now-batchStart).count();
227
+ double remT=max(0.0,TLms-elapsed);
228
+ int remSteps=max(1,nm-t);
229
+ double budget=remT*5.0/remSteps;
230
+ if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
231
+ batchStart=now;
232
+ stepCnt=0;
233
+ }
234
+ }
235
+ int H=(int)g+1;
236
+ int maxX=-1;
237
+ for(auto &pp:pl){
238
+ auto &t=ps[pp.idx].t[pp.ti];
239
+ for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}
240
+ }
241
+ int Wused=0;
242
+ if(maxX>=0){
243
+ vector<char> used(maxX+1,false);
244
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}}
245
+ for(int x=0;x<=maxX;x++) if(used[x]) Wused++;
246
+ }
247
+ int Wfinal=max(0,Wused);
248
+ long long A=1LL*H*max(1,Wfinal);
249
+ return R{A,max(1,Wfinal),H,move(pl)};
250
+ };
251
+ int minW=0; for(auto &p:ps) minW=max(minW,p.minW);
252
+
253
+ // Improved width estimation
254
+ double factor;
255
+ if (S < 1000) factor = 0.4;
256
+ else if (S < 3000) factor = 0.5;
257
+ else if (S < 10000) factor = 0.27;
258
+ else if (S < 30000) factor = 0.08;
259
+ else factor = 0.01;
260
+
261
+ int base = max(minW, (int)floor(sqrt((double)S * factor)));
262
+ vector<int> Ws;
263
+ {
264
+ unordered_set<int> used; used.reserve(512);
265
+ auto addW=[&](int w){if(w<minW) w=minW; if(used.insert(w).second) Ws.push_back(w);};
266
+ addW(base);
267
+ int span=min(96,max(20,base/2));
268
+ for(int d=1;d<=span;d++){addW(base-d); addW(base+d);}
269
+ addW(minW);
270
+ addW((int)max<long long>(minW,(S+base-1)/base));
271
+ for(int m=2;m<=6;m++){addW(base*m/3); addW((int)max<long long>(minW,S/((base*m/3)?(base*m/3):1)));}
272
+ // Add sqrt(S) based widths for more square-like rectangles
273
+ int sqrtS = max(minW, (int)floor(sqrt((double)S)));
274
+ addW(sqrtS);
275
+ addW(sqrtS+1);
276
+ addW(sqrtS-1);
277
+ addW(sqrtS*2/3);
278
+ addW(sqrtS/2);
279
+ sort(Ws.begin(),Ws.end(),[&](int a,int b){int da=abs(a-base),db=abs(b-base); if(da!=db) return da<db; return a<b;});
280
+ }
281
+ long long bestA=LLONG_MAX; int bestW=0,bestH=0; R bestR; bool hasBestmine=false;
282
+ auto t0=chrono::steady_clock::now();
283
+ const double TL=1980.0;
284
+ double avg=250.0; int cnt=0;
285
+
286
+ // Prepare multiple orderings
287
+ vector<vector<int>> base_orders;
288
+ base_orders.push_back(ord_asc_mindim());
289
+ base_orders.push_back(ord_desc_area());
290
+ base_orders.push_back(ord_desc_maxdim());
291
+ base_orders.push_back(ord_desc_bbox());
292
+
293
+ for(int wi=0;wi<(int)Ws.size();wi++){
294
+ auto now=chrono::steady_clock::now();
295
+ double used_time=chrono::duration<double,milli>(now-t0).count();
296
+ if(used_time+avg*1.3>TL) break;
297
+ int W=Ws[wi];
298
+
299
+ // Try each base ordering
300
+ for(int oi=0;oi<(int)base_orders.size();oi++){
301
+ now=chrono::steady_clock::now();
302
+ double used2=chrono::duration<double,milli>(now-t0).count();
303
+ if(used2+avg*1.15>TL) break;
304
+ bool randtie=(oi>=1);
305
+ auto t1=chrono::steady_clock::now();
306
+ R r=pack(W,base_orders[oi],rng,randtie);
307
+ auto t2=chrono::steady_clock::now();
308
+ double dt=chrono::duration<double,milli>(t2-t1).count();
309
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
310
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
311
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
312
+ }
313
+ }
314
+
315
+ // Also try random orderings if time permits
316
+ for(int ri=0;ri<2;ri++){
317
+ now=chrono::steady_clock::now();
318
+ double used2=chrono::duration<double,milli>(now-t0).count();
319
+ if(used2+avg*1.15>TL) break;
320
+ auto t1=chrono::steady_clock::now();
321
+ R r=pack(W,ord_random(),rng,true);
322
+ auto t2=chrono::steady_clock::now();
323
+ double dt=chrono::duration<double,milli>(t2-t1).count();
324
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
325
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
326
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
327
+ }
328
+ }
329
+ }
330
+ if(!hasBestmine){
331
+ int W=max(minW,(int)floor(sqrt((double)S)));
332
+ auto o=ord_asc_mindim();
333
+ R r=pack(W,o,rng,false);
334
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
335
+ }
336
+ int maxX=-1;
337
+ for(auto &p:bestR.pl){
338
+ auto &t=ps[p.idx].t[p.ti];
339
+ for(auto &q:t.c){int x=p.x+q.first; if(x>maxX) maxX=x;}
340
+ }
341
+ vector<int> mapx(maxX+1,-1);
342
+ if(maxX>=0){
343
+ vector<char> used(maxX+1,false);
344
+ for(auto &p:bestR.pl){
345
+ auto &t=ps[p.idx].t[p.ti];
346
+ for(auto &q:t.c){used[p.x+q.first]=true;}
347
+ }
348
+ int cur=0;
349
+ for(int x=0;x<=maxX;x++) if(used[x]) mapx[x]=cur++;
350
+ }
351
+ vector<array<int,4>> ans(n,{0,0,0,0});
352
+ for(auto &p:bestR.pl){
353
+ auto &t=ps[p.idx].t[p.ti];
354
+ int bx = (mapx.empty()?p.x:mapx[p.x]);
355
+ int Xi = bx - t.minx;
356
+ int Yi = p.y - t.miny;
357
+ int Ri = (4 - (t.r%4) + 4) % 4;
358
+ int Fi = t.f;
359
+ ans[p.idx]={Xi,Yi,Ri,Fi};
360
+ }
361
+ cout<<bestR.W<<" "<<bestR.H<<"\n";
362
+ for(int i=0;i<n;i++){
363
+ cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<"\n";
364
+ }
365
+ return 0;
366
+ }
docker_space/frontier_cs_0_polyomino_ev2/logs/gen_18.cpp ADDED
@@ -0,0 +1,515 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Gen 1: Multiple orderings + improved width search
3
+ Based on reference.cpp with:
4
+ - 4 ordering strategies (ascending min dim, descending area, descending max dim, random)
5
+ - Each width tries all orderings (time permitting)
6
+ - Better width candidate generation
7
+ */
8
+ #include <bits/stdc++.h>
9
+ using namespace std;
10
+ struct T{int w,h;vector<pair<int,int>> c;vector<int> lo,hi;int r,f,minx,miny;};
11
+ struct P{int id,k;vector<pair<int,int>> b;vector<T> t;int minW=1e9,minH=1e9,minA=1e9;};
12
+ struct Pl{int idx,ti,x,y;};
13
+ struct R{long long A;int W,H;vector<Pl> pl;};
14
+ struct RNG{unsigned long long s;RNG(unsigned long long x){s=x?x:1;}inline unsigned long long nxt(){s^=s<<7;s^=s>>9;return s;}inline int rint(int n){return (int)(nxt()%n);}inline bool coin(){return nxt()&1;}};
15
+ static inline pair<int,int> rotp(pair<int,int> p,int r){if(r==0)return p; if(r==1)return make_pair(-p.second,p.first); if(r==2)return make_pair(-p.first,-p.second); return make_pair(p.second,-p.first);}
16
+ int main(){
17
+ ios::sync_with_stdio(false);
18
+ cin.tie(nullptr);
19
+ int n; if(!(cin>>n)) return 0;
20
+ vector<P> ps(n); long long S=0;
21
+ for(int i=0;i<n;i++){
22
+ int k;cin>>k; ps[i].id=i+1; ps[i].k=k; ps[i].b.resize(k);
23
+ for(int j=0;j<k;j++){int x,y;cin>>x>>y; ps[i].b[j]={x,y};}
24
+ S+=k;
25
+ }
26
+ for(int i=0;i<n;i++){
27
+ auto &p=ps[i]; unordered_set<string> seen; seen.reserve(32);
28
+ for(int rf=0;rf<2;rf++){
29
+ vector<pair<int,int>> src=p.b; if(rf){for(auto &q:src) q.first=-q.first;}
30
+ for(int r=0;r<4;r++){
31
+ vector<pair<int,int>> v=src; for(auto &q:v) q=rotp(q,r);
32
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
33
+ for(auto &q:v){minx=min(minx,q.first);miny=min(miny,q.second);maxx=max(maxx,q.first);maxy=max(maxy,q.second);}
34
+ vector<pair<int,int>> v2=v; for(auto &q:v2){q.first-=minx;q.second-=miny;}
35
+ sort(v2.begin(),v2.end());
36
+ string key; key.reserve(v2.size()*8);
37
+ for(auto &q:v2){key.append(to_string(q.first));key.push_back(',');key.append(to_string(q.second));key.push_back(';');}
38
+ if(seen.insert(key).second){
39
+ T t; t.w=maxx-minx+1; t.h=maxy-miny+1; t.c=v2; t.r=r; t.f=rf; t.minx=minx; t.miny=miny;
40
+ t.lo.assign(t.w,INT_MAX); t.hi.assign(t.w,INT_MIN);
41
+ for(auto &q:v2){int x=q.first,y=q.second; if(t.lo[x]>y) t.lo[x]=y; if(t.hi[x]<y) t.hi[x]=y;}
42
+ p.t.push_back(move(t));
43
+ }
44
+ }
45
+ }
46
+ for(auto &t:p.t){p.minW=min(p.minW,t.w); p.minH=min(p.minH,t.h); p.minA=min(p.minA,t.w*t.h);}
47
+ if(p.t.empty()){T t; t.w=1;t.h=1;t.c={{0,0}};t.lo={0};t.hi={0};t.r=0;t.f=0;t.minx=0;t.miny=0;p.t.push_back(t);p.minW=1;p.minH=1;p.minA=1;}
48
+ }
49
+ vector<int> idx(n); iota(idx.begin(),idx.end(),0);
50
+ unsigned long long seed=((unsigned long long)chrono::high_resolution_clock::now().time_since_epoch().count()) ^ (S<<1) ^ (unsigned long long)(n*1469598103934665603ULL);
51
+ RNG rng(seed);
52
+
53
+ // Multiple ordering strategies
54
+ auto ord_asc_mindim = [&]() {
55
+ vector<int> res = idx;
56
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
57
+ int da = min(ps[a].minW, ps[a].minH);
58
+ int db = min(ps[b].minW, ps[b].minH);
59
+ if (da != db) return da < db;
60
+ if (ps[a].k != ps[b].k) return ps[a].k < ps[b].k;
61
+ return ps[a].id > ps[b].id;
62
+ });
63
+ return res;
64
+ };
65
+ auto ord_desc_area = [&]() {
66
+ vector<int> res = idx;
67
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
68
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
69
+ int da = min(ps[a].minW, ps[a].minH);
70
+ int db = min(ps[b].minW, ps[b].minH);
71
+ if (da != db) return da > db;
72
+ return ps[a].id < ps[b].id;
73
+ });
74
+ return res;
75
+ };
76
+ auto ord_desc_maxdim = [&]() {
77
+ vector<int> res = idx;
78
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
79
+ int da = max(ps[a].minW, ps[a].minH);
80
+ int db = max(ps[b].minW, ps[b].minH);
81
+ if (da != db) return da > db;
82
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
83
+ return ps[a].id < ps[b].id;
84
+ });
85
+ return res;
86
+ };
87
+ auto ord_desc_bbox = [&]() {
88
+ vector<int> res = idx;
89
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
90
+ if (ps[a].minA != ps[b].minA) return ps[a].minA > ps[b].minA;
91
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
92
+ return ps[a].id < ps[b].id;
93
+ });
94
+ return res;
95
+ };
96
+ auto ord_random = [&]() {
97
+ vector<int> res = idx;
98
+ for(int i=n-1;i>0;i--){
99
+ int j=rng.rint(i+1);
100
+ swap(res[i],res[j]);
101
+ }
102
+ return res;
103
+ };
104
+ // Perturb a given ordering by making random swaps
105
+ auto ord_perturb = [&](const vector<int>& base_ord, int nswaps) {
106
+ vector<int> res = base_ord;
107
+ for(int i=0;i<nswaps;i++){
108
+ int a=rng.rint(n), b=rng.rint(n);
109
+ swap(res[a],res[b]);
110
+ }
111
+ return res;
112
+ };
113
+ // Sort by flexibility (fewer variants first = harder to place)
114
+ auto ord_flexibility = [&]() {
115
+ vector<int> res = idx;
116
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
117
+ int va=(int)ps[a].t.size(), vb=(int)ps[b].t.size();
118
+ if(va!=vb) return va<vb;
119
+ if(ps[a].k!=ps[b].k) return ps[a].k>ps[b].k;
120
+ return ps[a].id<ps[b].id;
121
+ });
122
+ return res;
123
+ };
124
+
125
+ auto pack=[&](int W,const vector<int>& o0,RNG &rng,bool randtie){
126
+ vector<int> h(W,-1);
127
+ long long g=-1;
128
+ vector<Pl> pl; pl.reserve(o0.size());
129
+ vector<int> o=o0;
130
+ int t=0,nm=(int)o.size();
131
+ bool big=S>7000;
132
+ int maxBound=max(1,n/4);
133
+ int expLIM=min(maxBound,(int)(350000/max(1LL,S-3500)));
134
+ int dynLIM=big?expLIM:maxBound;
135
+ auto tStart=chrono::steady_clock::now();
136
+ auto batchStart=tStart;
137
+ long long TLms=big?1900:LLONG_MAX/4;
138
+ int stepCnt=0;
139
+ while(t<nm){
140
+ // Increase lookahead for early pieces (they have most impact)
141
+ int earlyBoost = (t < nm/10) ? min(3, max(1, maxBound/dynLIM)) : 1;
142
+ int limCnt=max(1,dynLIM * earlyBoost);
143
+ int lim=min(nm,t+limCnt);
144
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t; int bestid=-1;
145
+ for(int pos=t;pos<lim;pos++){
146
+ int id=o[pos];
147
+ auto &p=ps[id];
148
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
149
+ for(int ti=0;ti<(int)p.t.size();ti++){
150
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
151
+ for(int x0=0;x0<Rpos;x0++){
152
+ int y0=0;
153
+ for(int j=0;j<tsh.w;j++){
154
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
155
+ }
156
+ int nhbuf[32];
157
+ int l=-1; long long dsum=0;
158
+ for(int j=0;j<tsh.w;j++){
159
+ int nh=h[x0+j];
160
+ if(tsh.hi[j]!=INT_MIN){
161
+ int cand=y0+tsh.hi[j];
162
+ if(nh<cand) nh=cand;
163
+ }
164
+ nhbuf[j]=nh;
165
+ if(nh>l) l=nh;
166
+ }
167
+ for(int j=0;j<tsh.w;j++){
168
+ int inc=nhbuf[j]-h[x0+j];
169
+ if(inc>0) dsum+=inc;
170
+ }
171
+ long long dr=0;
172
+ if(x0>0){
173
+ long long old=llabs((long long)h[x0]-h[x0-1]);
174
+ long long nw=llabs((long long)nhbuf[0]-h[x0-1]);
175
+ dr+=nw-old;
176
+ }
177
+ for(int j=0;j<tsh.w-1;j++){
178
+ long long old=llabs((long long)h[x0+j+1]-h[x0+j]);
179
+ long long nw=llabs((long long)nhbuf[j+1]-nhbuf[j]);
180
+ dr+=nw-old;
181
+ }
182
+ if(x0+tsh.w<W){
183
+ long long old=llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);
184
+ long long nw=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1]);
185
+ dr+=nw-old;
186
+ }
187
+ long long gg=g; if(gg<l) gg=l;
188
+ bool take=false;
189
+ if(gg<bestg2) take=true;
190
+ else if(gg==bestg2){
191
+ if(dsum<bds2) take=true;
192
+ else if(dsum==bds2){
193
+ if(l<bl2) take=true;
194
+ else if(l==bl2){
195
+ if(dr<bdr2) take=true;
196
+ else if(dr==bdr2){
197
+ if(y0<by02) take=true;
198
+ else if(y0==by02){
199
+ if(x0<bx02) take=true;
200
+ else if(x0==bx02 && randtie && rng.coin()) take=true;
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
206
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=y0;bl2=l;bds2=dsum;bdr2=dr;by02=y0;bx02=x0;}
207
+ }
208
+ }
209
+ if(bti2==-1) continue;
210
+ // Use waste = dsum - k for between-piece comparison (accounts for piece size)
211
+ long long waste2 = bds2 - p.k;
212
+ bool take=false;
213
+ if(bestg2<bestg) take=true;
214
+ else if(bestg2==bestg){
215
+ if(waste2<bds) take=true;
216
+ else if(waste2==bds){
217
+ if(bl2<bl) take=true;
218
+ else if(bl2==bl){
219
+ if(bdr2<bdr) take=true;
220
+ else if(bdr2==bdr){
221
+ if(by02<by0) take=true;
222
+ else if(by02==by0){
223
+ if(bx02<bx0) take=true;
224
+ else if(bx02==bx0 && randtie && rng.coin()) take=true;
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
231
+ }
232
+ if(bti==-1){t++;stepCnt++;if(big&&stepCnt==5){auto now=chrono::steady_clock::now(); auto elapsed=chrono::duration<double,milli>(now-tStart).count(); auto batch=chrono::duration<double,milli>(now-batchStart).count(); double remT=max(0.0,TLms-elapsed); int remSteps=max(1,nm-t); double budget=remT*5.0/remSteps; if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1); batchStart=now; stepCnt=0;} continue;}
233
+ auto &tsh=ps[bestid].t[bti];
234
+ for(int j=0;j<tsh.w;j++){
235
+ int nh=h[bx+j];
236
+ if(tsh.hi[j]!=INT_MIN){
237
+ int cand=by+tsh.hi[j];
238
+ if(nh<cand) nh=cand;
239
+ }
240
+ h[bx+j]=nh;
241
+ }
242
+ if(g<bl) g=bl;
243
+ pl.push_back({bestid,bti,bx,by});
244
+ if(bestpos!=t) swap(o[t],o[bestpos]);
245
+ t++;
246
+ stepCnt++;
247
+ if(big&&stepCnt==5){
248
+ auto now=chrono::steady_clock::now();
249
+ auto elapsed=chrono::duration<double,milli>(now-tStart).count();
250
+ auto batch=chrono::duration<double,milli>(now-batchStart).count();
251
+ double remT=max(0.0,TLms-elapsed);
252
+ int remSteps=max(1,nm-t);
253
+ double budget=remT*5.0/remSteps;
254
+ if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
255
+ batchStart=now;
256
+ stepCnt=0;
257
+ }
258
+ }
259
+ int H=(int)g+1;
260
+ int maxX=-1;
261
+ for(auto &pp:pl){
262
+ auto &t=ps[pp.idx].t[pp.ti];
263
+ for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}
264
+ }
265
+ int Wused=0;
266
+ if(maxX>=0){
267
+ vector<char> used(maxX+1,false);
268
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}}
269
+ for(int x=0;x<=maxX;x++) if(used[x]) Wused++;
270
+ }
271
+ int Wfinal=max(0,Wused);
272
+ long long A=1LL*H*max(1,Wfinal);
273
+ return R{A,max(1,Wfinal),H,move(pl)};
274
+ };
275
+ // Gap-filling pack for small inputs - tries positions below skyline using bitmap
276
+ auto pack_gap=[&](int W,const vector<int>& o0,RNG &rng,bool randtie) -> R {
277
+ int maxHg=(int)(S/max(1,W)+W+50);
278
+ vector<vector<bool>> grid(W, vector<bool>(maxHg, false));
279
+ vector<int> h(W,-1);
280
+ long long g=-1;
281
+ vector<Pl> pl; pl.reserve(o0.size());
282
+ vector<int> o=o0;
283
+ int t2=0,nm=(int)o.size();
284
+ int maxBound=max(1,n/4);
285
+ int dynLIM=maxBound;
286
+ bool gapEnabled=true;
287
+ while(t2<nm){
288
+ int earlyBoost=(t2<nm/10)?min(3,max(1,maxBound/dynLIM)):1;
289
+ int limCnt=max(1,dynLIM*earlyBoost);
290
+ int lim=min(nm,t2+limCnt);
291
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t2; int bestid=-1;
292
+ for(int pos=t2;pos<lim;pos++){
293
+ int id=o[pos];
294
+ auto &p=ps[id];
295
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
296
+ for(int ti=0;ti<(int)p.t.size();ti++){
297
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
298
+ for(int x0=0;x0<Rpos;x0++){
299
+ // Skyline placement
300
+ int y0=0;
301
+ for(int j=0;j<tsh.w;j++){
302
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
303
+ }
304
+ // Also try gap positions (scan up to 10 rows below skyline)
305
+ int gapY=-1;
306
+ if(gapEnabled && y0>0){
307
+ int sd=min(y0,3); // Only check 3 rows below skyline
308
+ for(int gy=max(0,y0-sd);gy<y0;gy++){
309
+ bool ok=true;
310
+ for(auto &q:tsh.c){
311
+ int gx=x0+q.first,gcy=gy+q.second;
312
+ if(gcy<0||gcy>=maxHg||grid[gx][gcy]){ok=false;break;}
313
+ }
314
+ if(ok){gapY=gy;break;}
315
+ }
316
+ }
317
+ // Evaluate both positions
318
+ for(int pass=0;pass<(gapY>=0?2:1);pass++){
319
+ int yy=(pass==0)?y0:gapY;
320
+ int nhbuf[32];
321
+ int l=-1; long long dsum=0;
322
+ for(int j=0;j<tsh.w;j++){
323
+ int nh=h[x0+j];
324
+ if(tsh.hi[j]!=INT_MIN){int cand=yy+tsh.hi[j]; if(nh<cand) nh=cand;}
325
+ nhbuf[j]=nh; if(nh>l) l=nh;
326
+ }
327
+ for(int j=0;j<tsh.w;j++){int inc=nhbuf[j]-h[x0+j]; if(inc>0) dsum+=inc;}
328
+ long long dr=0;
329
+ if(x0>0){dr+=llabs((long long)nhbuf[0]-h[x0-1])-llabs((long long)h[x0]-h[x0-1]);}
330
+ for(int j=0;j<tsh.w-1;j++){dr+=llabs((long long)nhbuf[j+1]-nhbuf[j])-llabs((long long)h[x0+j+1]-h[x0+j]);}
331
+ if(x0+tsh.w<W){dr+=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1])-llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);}
332
+ long long gg=g; if(gg<l) gg=l;
333
+ bool take=false;
334
+ if(gg<bestg2) take=true;
335
+ else if(gg==bestg2){
336
+ if(dsum<bds2) take=true;
337
+ else if(dsum==bds2){if(l<bl2) take=true;
338
+ else if(l==bl2){if(dr<bdr2) take=true;
339
+ else if(dr==bdr2){if(yy<by02) take=true;
340
+ else if(yy==by02){if(x0<bx02) take=true;
341
+ else if(x0==bx02&&randtie&&rng.coin()) take=true;}}}}
342
+ }
343
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=yy;bl2=l;bds2=dsum;bdr2=dr;by02=yy;bx02=x0;}
344
+ }
345
+ }
346
+ }
347
+ if(bti2==-1) continue;
348
+ long long waste2=bds2-p.k;
349
+ bool take=false;
350
+ if(bestg2<bestg) take=true;
351
+ else if(bestg2==bestg){if(waste2<bds) take=true;
352
+ else if(waste2==bds){if(bl2<bl) take=true;
353
+ else if(bl2==bl){if(bdr2<bdr) take=true;
354
+ else if(bdr2==bdr){if(by02<by0) take=true;
355
+ else if(by02==by0){if(bx02<bx0) take=true;
356
+ else if(bx02==bx0&&randtie&&rng.coin()) take=true;}}}}}
357
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
358
+ }
359
+ if(bti==-1){t2++;continue;}
360
+ auto &tsh=ps[bestid].t[bti];
361
+ for(int j=0;j<tsh.w;j++){
362
+ int nh=h[bx+j];
363
+ if(tsh.hi[j]!=INT_MIN){int cand=by+tsh.hi[j]; if(nh<cand) nh=cand;}
364
+ h[bx+j]=nh;
365
+ }
366
+ for(auto &q:tsh.c){int gx=bx+q.first,gy=by+q.second; if(gx>=0&&gx<W&&gy>=0&&gy<maxHg) grid[gx][gy]=true;}
367
+ if(g<bl) g=bl;
368
+ pl.push_back({bestid,bti,bx,by});
369
+ if(bestpos!=t2) swap(o[t2],o[bestpos]);
370
+ t2++;
371
+ }
372
+ if((int)pl.size() < nm){
373
+ // Not all pieces placed - return failure
374
+ return R{LLONG_MAX, W, 0, {}};
375
+ }
376
+ int H=(int)g+1;
377
+ int maxX=-1;
378
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}}
379
+ int Wused=0;
380
+ if(maxX>=0){vector<char> used(maxX+1,false); for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}} for(int x=0;x<=maxX;x++) if(used[x]) Wused++;}
381
+ int Wfinal=max(0,Wused);
382
+ long long A=1LL*H*max(1,Wfinal);
383
+ return R{A,max(1,Wfinal),H,move(pl)};
384
+ };
385
+ int minW=0; for(auto &p:ps) minW=max(minW,p.minW);
386
+
387
+ // Improved width estimation
388
+ double factor;
389
+ if (S < 1000) factor = 0.4;
390
+ else if (S < 3000) factor = 0.5;
391
+ else if (S < 10000) factor = 0.27;
392
+ else if (S < 30000) factor = 0.08;
393
+ else factor = 0.01;
394
+
395
+ int base = max(minW, (int)floor(sqrt((double)S * factor)));
396
+ vector<int> Ws;
397
+ {
398
+ unordered_set<int> used; used.reserve(512);
399
+ auto addW=[&](int w){if(w<minW) w=minW; if(used.insert(w).second) Ws.push_back(w);};
400
+ addW(base);
401
+ int span=min(96,max(20,base/2));
402
+ for(int d=1;d<=span;d++){addW(base-d); addW(base+d);}
403
+ addW(minW);
404
+ addW((int)max<long long>(minW,(S+base-1)/base));
405
+ for(int m=2;m<=6;m++){addW(base*m/3); addW((int)max<long long>(minW,S/((base*m/3)?(base*m/3):1)));}
406
+ // Add sqrt(S) based widths for more square-like rectangles
407
+ int sqrtS = max(minW, (int)floor(sqrt((double)S)));
408
+ addW(sqrtS);
409
+ addW(sqrtS+1);
410
+ addW(sqrtS-1);
411
+ addW(sqrtS*2/3);
412
+ addW(sqrtS/2);
413
+ sort(Ws.begin(),Ws.end(),[&](int a,int b){int da=abs(a-base),db=abs(b-base); if(da!=db) return da<db; return a<b;});
414
+ }
415
+ long long bestA=LLONG_MAX; int bestW=0,bestH=0; R bestR; bool hasBestmine=false;
416
+ auto t0=chrono::steady_clock::now();
417
+ const double TL=1980.0;
418
+ double avg=250.0; int cnt=0;
419
+
420
+ // Prepare multiple orderings
421
+ vector<vector<int>> base_orders;
422
+ base_orders.push_back(ord_asc_mindim());
423
+ base_orders.push_back(ord_desc_area());
424
+ base_orders.push_back(ord_desc_maxdim());
425
+ base_orders.push_back(ord_desc_bbox());
426
+ base_orders.push_back(ord_flexibility());
427
+
428
+ bool useGapPacker = (S < 2000); // Use gap-filling for small inputs
429
+ auto doPack = [&](int W, const vector<int>& order, RNG& rng, bool randtie) -> R {
430
+ if(useGapPacker) return pack_gap(W, order, rng, randtie);
431
+ return pack(W, order, rng, randtie);
432
+ };
433
+
434
+ // Track best ordering index per width for perturbation
435
+ int bestOrderIdx = 0;
436
+
437
+ for(int wi=0;wi<(int)Ws.size();wi++){
438
+ auto now=chrono::steady_clock::now();
439
+ double used_time=chrono::duration<double,milli>(now-t0).count();
440
+ if(used_time+avg*1.3>TL) break;
441
+ int W=Ws[wi];
442
+
443
+ // Try each base ordering
444
+ for(int oi=0;oi<(int)base_orders.size();oi++){
445
+ now=chrono::steady_clock::now();
446
+ double used2=chrono::duration<double,milli>(now-t0).count();
447
+ if(used2+avg*1.15>TL) break;
448
+ bool randtie=(oi>=1);
449
+ auto t1=chrono::steady_clock::now();
450
+ R r=doPack(W,base_orders[oi],rng,randtie);
451
+ auto t2=chrono::steady_clock::now();
452
+ double dt=chrono::duration<double,milli>(t2-t1).count();
453
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
454
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
455
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
456
+ bestOrderIdx=oi;
457
+ }
458
+ }
459
+
460
+ // Perturbation of best ordering + random orderings
461
+ int nswaps = max(1, n/20);
462
+ for(int ri=0;ri<4;ri++){
463
+ now=chrono::steady_clock::now();
464
+ double used2=chrono::duration<double,milli>(now-t0).count();
465
+ if(used2+avg*1.15>TL) break;
466
+ auto t1=chrono::steady_clock::now();
467
+ vector<int> order;
468
+ if(ri < 2) order = ord_perturb(base_orders[bestOrderIdx], nswaps);
469
+ else order = ord_random();
470
+ R r=doPack(W,order,rng,true);
471
+ auto t2=chrono::steady_clock::now();
472
+ double dt=chrono::duration<double,milli>(t2-t1).count();
473
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
474
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
475
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
476
+ }
477
+ }
478
+ }
479
+ if(!hasBestmine){
480
+ int W=max(minW,(int)floor(sqrt((double)S)));
481
+ auto o=ord_asc_mindim();
482
+ R r=pack(W,o,rng,false);
483
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
484
+ }
485
+ int maxX=-1;
486
+ for(auto &p:bestR.pl){
487
+ auto &t=ps[p.idx].t[p.ti];
488
+ for(auto &q:t.c){int x=p.x+q.first; if(x>maxX) maxX=x;}
489
+ }
490
+ vector<int> mapx(maxX+1,-1);
491
+ if(maxX>=0){
492
+ vector<char> used(maxX+1,false);
493
+ for(auto &p:bestR.pl){
494
+ auto &t=ps[p.idx].t[p.ti];
495
+ for(auto &q:t.c){used[p.x+q.first]=true;}
496
+ }
497
+ int cur=0;
498
+ for(int x=0;x<=maxX;x++) if(used[x]) mapx[x]=cur++;
499
+ }
500
+ vector<array<int,4>> ans(n,{0,0,0,0});
501
+ for(auto &p:bestR.pl){
502
+ auto &t=ps[p.idx].t[p.ti];
503
+ int bx = (mapx.empty()?p.x:mapx[p.x]);
504
+ int Xi = bx - t.minx;
505
+ int Yi = p.y - t.miny;
506
+ int Ri = (4 - (t.r%4) + 4) % 4;
507
+ int Fi = t.f;
508
+ ans[p.idx]={Xi,Yi,Ri,Fi};
509
+ }
510
+ cout<<bestR.W<<" "<<bestR.H<<"\n";
511
+ for(int i=0;i<n;i++){
512
+ cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<"\n";
513
+ }
514
+ return 0;
515
+ }
docker_space/frontier_cs_0_polyomino_ev2/logs/gen_20.cpp ADDED
@@ -0,0 +1,515 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Gen 1: Multiple orderings + improved width search
3
+ Based on reference.cpp with:
4
+ - 4 ordering strategies (ascending min dim, descending area, descending max dim, random)
5
+ - Each width tries all orderings (time permitting)
6
+ - Better width candidate generation
7
+ */
8
+ #include <bits/stdc++.h>
9
+ using namespace std;
10
+ struct T{int w,h;vector<pair<int,int>> c;vector<int> lo,hi;int r,f,minx,miny;};
11
+ struct P{int id,k;vector<pair<int,int>> b;vector<T> t;int minW=1e9,minH=1e9,minA=1e9;};
12
+ struct Pl{int idx,ti,x,y;};
13
+ struct R{long long A;int W,H;vector<Pl> pl;};
14
+ struct RNG{unsigned long long s;RNG(unsigned long long x){s=x?x:1;}inline unsigned long long nxt(){s^=s<<7;s^=s>>9;return s;}inline int rint(int n){return (int)(nxt()%n);}inline bool coin(){return nxt()&1;}};
15
+ static inline pair<int,int> rotp(pair<int,int> p,int r){if(r==0)return p; if(r==1)return make_pair(-p.second,p.first); if(r==2)return make_pair(-p.first,-p.second); return make_pair(p.second,-p.first);}
16
+ int main(){
17
+ ios::sync_with_stdio(false);
18
+ cin.tie(nullptr);
19
+ int n; if(!(cin>>n)) return 0;
20
+ vector<P> ps(n); long long S=0;
21
+ for(int i=0;i<n;i++){
22
+ int k;cin>>k; ps[i].id=i+1; ps[i].k=k; ps[i].b.resize(k);
23
+ for(int j=0;j<k;j++){int x,y;cin>>x>>y; ps[i].b[j]={x,y};}
24
+ S+=k;
25
+ }
26
+ for(int i=0;i<n;i++){
27
+ auto &p=ps[i]; unordered_set<string> seen; seen.reserve(32);
28
+ for(int rf=0;rf<2;rf++){
29
+ vector<pair<int,int>> src=p.b; if(rf){for(auto &q:src) q.first=-q.first;}
30
+ for(int r=0;r<4;r++){
31
+ vector<pair<int,int>> v=src; for(auto &q:v) q=rotp(q,r);
32
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
33
+ for(auto &q:v){minx=min(minx,q.first);miny=min(miny,q.second);maxx=max(maxx,q.first);maxy=max(maxy,q.second);}
34
+ vector<pair<int,int>> v2=v; for(auto &q:v2){q.first-=minx;q.second-=miny;}
35
+ sort(v2.begin(),v2.end());
36
+ string key; key.reserve(v2.size()*8);
37
+ for(auto &q:v2){key.append(to_string(q.first));key.push_back(',');key.append(to_string(q.second));key.push_back(';');}
38
+ if(seen.insert(key).second){
39
+ T t; t.w=maxx-minx+1; t.h=maxy-miny+1; t.c=v2; t.r=r; t.f=rf; t.minx=minx; t.miny=miny;
40
+ t.lo.assign(t.w,INT_MAX); t.hi.assign(t.w,INT_MIN);
41
+ for(auto &q:v2){int x=q.first,y=q.second; if(t.lo[x]>y) t.lo[x]=y; if(t.hi[x]<y) t.hi[x]=y;}
42
+ p.t.push_back(move(t));
43
+ }
44
+ }
45
+ }
46
+ for(auto &t:p.t){p.minW=min(p.minW,t.w); p.minH=min(p.minH,t.h); p.minA=min(p.minA,t.w*t.h);}
47
+ if(p.t.empty()){T t; t.w=1;t.h=1;t.c={{0,0}};t.lo={0};t.hi={0};t.r=0;t.f=0;t.minx=0;t.miny=0;p.t.push_back(t);p.minW=1;p.minH=1;p.minA=1;}
48
+ }
49
+ vector<int> idx(n); iota(idx.begin(),idx.end(),0);
50
+ unsigned long long seed=((unsigned long long)chrono::high_resolution_clock::now().time_since_epoch().count()) ^ (S<<1) ^ (unsigned long long)(n*1469598103934665603ULL);
51
+ RNG rng(seed);
52
+
53
+ // Multiple ordering strategies
54
+ auto ord_asc_mindim = [&]() {
55
+ vector<int> res = idx;
56
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
57
+ int da = min(ps[a].minW, ps[a].minH);
58
+ int db = min(ps[b].minW, ps[b].minH);
59
+ if (da != db) return da < db;
60
+ if (ps[a].k != ps[b].k) return ps[a].k < ps[b].k;
61
+ return ps[a].id > ps[b].id;
62
+ });
63
+ return res;
64
+ };
65
+ auto ord_desc_area = [&]() {
66
+ vector<int> res = idx;
67
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
68
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
69
+ int da = min(ps[a].minW, ps[a].minH);
70
+ int db = min(ps[b].minW, ps[b].minH);
71
+ if (da != db) return da > db;
72
+ return ps[a].id < ps[b].id;
73
+ });
74
+ return res;
75
+ };
76
+ auto ord_desc_maxdim = [&]() {
77
+ vector<int> res = idx;
78
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
79
+ int da = max(ps[a].minW, ps[a].minH);
80
+ int db = max(ps[b].minW, ps[b].minH);
81
+ if (da != db) return da > db;
82
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
83
+ return ps[a].id < ps[b].id;
84
+ });
85
+ return res;
86
+ };
87
+ auto ord_desc_bbox = [&]() {
88
+ vector<int> res = idx;
89
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
90
+ if (ps[a].minA != ps[b].minA) return ps[a].minA > ps[b].minA;
91
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
92
+ return ps[a].id < ps[b].id;
93
+ });
94
+ return res;
95
+ };
96
+ auto ord_random = [&]() {
97
+ vector<int> res = idx;
98
+ for(int i=n-1;i>0;i--){
99
+ int j=rng.rint(i+1);
100
+ swap(res[i],res[j]);
101
+ }
102
+ return res;
103
+ };
104
+ // Perturb a given ordering by making random swaps
105
+ auto ord_perturb = [&](const vector<int>& base_ord, int nswaps) {
106
+ vector<int> res = base_ord;
107
+ for(int i=0;i<nswaps;i++){
108
+ int a=rng.rint(n), b=rng.rint(n);
109
+ swap(res[a],res[b]);
110
+ }
111
+ return res;
112
+ };
113
+ // Sort by flexibility (fewer variants first = harder to place)
114
+ auto ord_flexibility = [&]() {
115
+ vector<int> res = idx;
116
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
117
+ int va=(int)ps[a].t.size(), vb=(int)ps[b].t.size();
118
+ if(va!=vb) return va<vb;
119
+ if(ps[a].k!=ps[b].k) return ps[a].k>ps[b].k;
120
+ return ps[a].id<ps[b].id;
121
+ });
122
+ return res;
123
+ };
124
+
125
+ auto pack=[&](int W,const vector<int>& o0,RNG &rng,bool randtie){
126
+ vector<int> h(W,-1);
127
+ long long g=-1;
128
+ vector<Pl> pl; pl.reserve(o0.size());
129
+ vector<int> o=o0;
130
+ int t=0,nm=(int)o.size();
131
+ bool big=S>7000;
132
+ int maxBound=max(1,n/4);
133
+ int expLIM=min(maxBound,(int)(350000/max(1LL,S-3500)));
134
+ int dynLIM=big?expLIM:maxBound;
135
+ auto tStart=chrono::steady_clock::now();
136
+ auto batchStart=tStart;
137
+ long long TLms=big?1900:LLONG_MAX/4;
138
+ int stepCnt=0;
139
+ while(t<nm){
140
+ // Increase lookahead for early pieces (they have most impact)
141
+ int earlyBoost = (t < nm/10) ? min(3, max(1, maxBound/dynLIM)) : 1;
142
+ int limCnt=max(1,dynLIM * earlyBoost);
143
+ int lim=min(nm,t+limCnt);
144
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t; int bestid=-1;
145
+ for(int pos=t;pos<lim;pos++){
146
+ int id=o[pos];
147
+ auto &p=ps[id];
148
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
149
+ for(int ti=0;ti<(int)p.t.size();ti++){
150
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
151
+ for(int x0=0;x0<Rpos;x0++){
152
+ int y0=0;
153
+ for(int j=0;j<tsh.w;j++){
154
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
155
+ }
156
+ int nhbuf[32];
157
+ int l=-1; long long dsum=0;
158
+ for(int j=0;j<tsh.w;j++){
159
+ int nh=h[x0+j];
160
+ if(tsh.hi[j]!=INT_MIN){
161
+ int cand=y0+tsh.hi[j];
162
+ if(nh<cand) nh=cand;
163
+ }
164
+ nhbuf[j]=nh;
165
+ if(nh>l) l=nh;
166
+ }
167
+ for(int j=0;j<tsh.w;j++){
168
+ int inc=nhbuf[j]-h[x0+j];
169
+ if(inc>0) dsum+=inc;
170
+ }
171
+ long long dr=0;
172
+ if(x0>0){
173
+ long long old=llabs((long long)h[x0]-h[x0-1]);
174
+ long long nw=llabs((long long)nhbuf[0]-h[x0-1]);
175
+ dr+=nw-old;
176
+ }
177
+ for(int j=0;j<tsh.w-1;j++){
178
+ long long old=llabs((long long)h[x0+j+1]-h[x0+j]);
179
+ long long nw=llabs((long long)nhbuf[j+1]-nhbuf[j]);
180
+ dr+=nw-old;
181
+ }
182
+ if(x0+tsh.w<W){
183
+ long long old=llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);
184
+ long long nw=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1]);
185
+ dr+=nw-old;
186
+ }
187
+ long long gg=g; if(gg<l) gg=l;
188
+ bool take=false;
189
+ if(gg<bestg2) take=true;
190
+ else if(gg==bestg2){
191
+ if(dsum<bds2) take=true;
192
+ else if(dsum==bds2){
193
+ if(l<bl2) take=true;
194
+ else if(l==bl2){
195
+ if(dr<bdr2) take=true;
196
+ else if(dr==bdr2){
197
+ if(y0<by02) take=true;
198
+ else if(y0==by02){
199
+ if(x0<bx02) take=true;
200
+ else if(x0==bx02 && randtie && rng.coin()) take=true;
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
206
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=y0;bl2=l;bds2=dsum;bdr2=dr;by02=y0;bx02=x0;}
207
+ }
208
+ }
209
+ if(bti2==-1) continue;
210
+ // Use waste = dsum - k for between-piece comparison (accounts for piece size)
211
+ long long waste2 = bds2 - p.k;
212
+ bool take=false;
213
+ if(bestg2<bestg) take=true;
214
+ else if(bestg2==bestg){
215
+ if(waste2<bds) take=true;
216
+ else if(waste2==bds){
217
+ if(bl2<bl) take=true;
218
+ else if(bl2==bl){
219
+ if(bdr2<bdr) take=true;
220
+ else if(bdr2==bdr){
221
+ if(by02<by0) take=true;
222
+ else if(by02==by0){
223
+ if(bx02<bx0) take=true;
224
+ else if(bx02==bx0 && randtie && rng.coin()) take=true;
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
231
+ }
232
+ if(bti==-1){t++;stepCnt++;if(big&&stepCnt==5){auto now=chrono::steady_clock::now(); auto elapsed=chrono::duration<double,milli>(now-tStart).count(); auto batch=chrono::duration<double,milli>(now-batchStart).count(); double remT=max(0.0,TLms-elapsed); int remSteps=max(1,nm-t); double budget=remT*5.0/remSteps; if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1); batchStart=now; stepCnt=0;} continue;}
233
+ auto &tsh=ps[bestid].t[bti];
234
+ for(int j=0;j<tsh.w;j++){
235
+ int nh=h[bx+j];
236
+ if(tsh.hi[j]!=INT_MIN){
237
+ int cand=by+tsh.hi[j];
238
+ if(nh<cand) nh=cand;
239
+ }
240
+ h[bx+j]=nh;
241
+ }
242
+ if(g<bl) g=bl;
243
+ pl.push_back({bestid,bti,bx,by});
244
+ if(bestpos!=t) swap(o[t],o[bestpos]);
245
+ t++;
246
+ stepCnt++;
247
+ if(big&&stepCnt==5){
248
+ auto now=chrono::steady_clock::now();
249
+ auto elapsed=chrono::duration<double,milli>(now-tStart).count();
250
+ auto batch=chrono::duration<double,milli>(now-batchStart).count();
251
+ double remT=max(0.0,TLms-elapsed);
252
+ int remSteps=max(1,nm-t);
253
+ double budget=remT*5.0/remSteps;
254
+ if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
255
+ batchStart=now;
256
+ stepCnt=0;
257
+ }
258
+ }
259
+ int H=(int)g+1;
260
+ int maxX=-1;
261
+ for(auto &pp:pl){
262
+ auto &t=ps[pp.idx].t[pp.ti];
263
+ for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}
264
+ }
265
+ int Wused=0;
266
+ if(maxX>=0){
267
+ vector<char> used(maxX+1,false);
268
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}}
269
+ for(int x=0;x<=maxX;x++) if(used[x]) Wused++;
270
+ }
271
+ int Wfinal=max(0,Wused);
272
+ long long A=1LL*H*max(1,Wfinal);
273
+ return R{A,max(1,Wfinal),H,move(pl)};
274
+ };
275
+ // Gap-filling pack for small inputs - tries positions below skyline using bitmap
276
+ auto pack_gap=[&](int W,const vector<int>& o0,RNG &rng,bool randtie) -> R {
277
+ int maxHg=(int)(S/max(1,W)+W+50);
278
+ vector<vector<bool>> grid(W, vector<bool>(maxHg, false));
279
+ vector<int> h(W,-1);
280
+ long long g=-1;
281
+ vector<Pl> pl; pl.reserve(o0.size());
282
+ vector<int> o=o0;
283
+ int t2=0,nm=(int)o.size();
284
+ int maxBound=max(1,n/4);
285
+ int dynLIM=maxBound;
286
+ bool gapEnabled=true;
287
+ while(t2<nm){
288
+ int earlyBoost=(t2<nm/10)?min(3,max(1,maxBound/dynLIM)):1;
289
+ int limCnt=max(1,dynLIM*earlyBoost);
290
+ int lim=min(nm,t2+limCnt);
291
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t2; int bestid=-1;
292
+ for(int pos=t2;pos<lim;pos++){
293
+ int id=o[pos];
294
+ auto &p=ps[id];
295
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
296
+ for(int ti=0;ti<(int)p.t.size();ti++){
297
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
298
+ for(int x0=0;x0<Rpos;x0++){
299
+ // Skyline placement
300
+ int y0=0;
301
+ for(int j=0;j<tsh.w;j++){
302
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
303
+ }
304
+ // Also try gap positions (scan up to 10 rows below skyline)
305
+ int gapY=-1;
306
+ if(gapEnabled && y0>0){
307
+ int sd=min(y0,3); // Only check 3 rows below skyline
308
+ for(int gy=max(0,y0-sd);gy<y0;gy++){
309
+ bool ok=true;
310
+ for(auto &q:tsh.c){
311
+ int gx=x0+q.first,gcy=gy+q.second;
312
+ if(gcy<0||gcy>=maxHg||grid[gx][gcy]){ok=false;break;}
313
+ }
314
+ if(ok){gapY=gy;break;}
315
+ }
316
+ }
317
+ // Evaluate both positions
318
+ for(int pass=0;pass<(gapY>=0?2:1);pass++){
319
+ int yy=(pass==0)?y0:gapY;
320
+ int nhbuf[32];
321
+ int l=-1; long long dsum=0;
322
+ for(int j=0;j<tsh.w;j++){
323
+ int nh=h[x0+j];
324
+ if(tsh.hi[j]!=INT_MIN){int cand=yy+tsh.hi[j]; if(nh<cand) nh=cand;}
325
+ nhbuf[j]=nh; if(nh>l) l=nh;
326
+ }
327
+ for(int j=0;j<tsh.w;j++){int inc=nhbuf[j]-h[x0+j]; if(inc>0) dsum+=inc;}
328
+ long long dr=0;
329
+ if(x0>0){dr+=llabs((long long)nhbuf[0]-h[x0-1])-llabs((long long)h[x0]-h[x0-1]);}
330
+ for(int j=0;j<tsh.w-1;j++){dr+=llabs((long long)nhbuf[j+1]-nhbuf[j])-llabs((long long)h[x0+j+1]-h[x0+j]);}
331
+ if(x0+tsh.w<W){dr+=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1])-llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);}
332
+ long long gg=g; if(gg<l) gg=l;
333
+ bool take=false;
334
+ if(gg<bestg2) take=true;
335
+ else if(gg==bestg2){
336
+ if(dsum<bds2) take=true;
337
+ else if(dsum==bds2){if(l<bl2) take=true;
338
+ else if(l==bl2){if(dr<bdr2) take=true;
339
+ else if(dr==bdr2){if(yy<by02) take=true;
340
+ else if(yy==by02){if(x0<bx02) take=true;
341
+ else if(x0==bx02&&randtie&&rng.coin()) take=true;}}}}
342
+ }
343
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=yy;bl2=l;bds2=dsum;bdr2=dr;by02=yy;bx02=x0;}
344
+ }
345
+ }
346
+ }
347
+ if(bti2==-1) continue;
348
+ long long waste2=bds2-p.k;
349
+ bool take=false;
350
+ if(bestg2<bestg) take=true;
351
+ else if(bestg2==bestg){if(waste2<bds) take=true;
352
+ else if(waste2==bds){if(bl2<bl) take=true;
353
+ else if(bl2==bl){if(bdr2<bdr) take=true;
354
+ else if(bdr2==bdr){if(by02<by0) take=true;
355
+ else if(by02==by0){if(bx02<bx0) take=true;
356
+ else if(bx02==bx0&&randtie&&rng.coin()) take=true;}}}}}
357
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
358
+ }
359
+ if(bti==-1){t2++;continue;}
360
+ auto &tsh=ps[bestid].t[bti];
361
+ for(int j=0;j<tsh.w;j++){
362
+ int nh=h[bx+j];
363
+ if(tsh.hi[j]!=INT_MIN){int cand=by+tsh.hi[j]; if(nh<cand) nh=cand;}
364
+ h[bx+j]=nh;
365
+ }
366
+ for(auto &q:tsh.c){int gx=bx+q.first,gy=by+q.second; if(gx>=0&&gx<W&&gy>=0&&gy<maxHg) grid[gx][gy]=true;}
367
+ if(g<bl) g=bl;
368
+ pl.push_back({bestid,bti,bx,by});
369
+ if(bestpos!=t2) swap(o[t2],o[bestpos]);
370
+ t2++;
371
+ }
372
+ if((int)pl.size() < nm){
373
+ // Not all pieces placed - return failure
374
+ return R{LLONG_MAX, W, 0, {}};
375
+ }
376
+ int H=(int)g+1;
377
+ int maxX=-1;
378
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}}
379
+ int Wused=0;
380
+ if(maxX>=0){vector<char> used(maxX+1,false); for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}} for(int x=0;x<=maxX;x++) if(used[x]) Wused++;}
381
+ int Wfinal=max(0,Wused);
382
+ long long A=1LL*H*max(1,Wfinal);
383
+ return R{A,max(1,Wfinal),H,move(pl)};
384
+ };
385
+ int minW=0; for(auto &p:ps) minW=max(minW,p.minW);
386
+
387
+ // Improved width estimation
388
+ double factor;
389
+ if (S < 1000) factor = 0.4;
390
+ else if (S < 3000) factor = 0.5;
391
+ else if (S < 10000) factor = 0.27;
392
+ else if (S < 30000) factor = 0.08;
393
+ else factor = 0.01;
394
+
395
+ int base = max(minW, (int)floor(sqrt((double)S * factor)));
396
+ vector<int> Ws;
397
+ {
398
+ unordered_set<int> used; used.reserve(512);
399
+ auto addW=[&](int w){if(w<minW) w=minW; if(used.insert(w).second) Ws.push_back(w);};
400
+ addW(base);
401
+ int span=min(96,max(20,base/2));
402
+ for(int d=1;d<=span;d++){addW(base-d); addW(base+d);}
403
+ addW(minW);
404
+ addW((int)max<long long>(minW,(S+base-1)/base));
405
+ for(int m=2;m<=6;m++){addW(base*m/3); addW((int)max<long long>(minW,S/((base*m/3)?(base*m/3):1)));}
406
+ // Add sqrt(S) based widths for more square-like rectangles
407
+ int sqrtS = max(minW, (int)floor(sqrt((double)S)));
408
+ addW(sqrtS);
409
+ addW(sqrtS+1);
410
+ addW(sqrtS-1);
411
+ addW(sqrtS*2/3);
412
+ addW(sqrtS/2);
413
+ sort(Ws.begin(),Ws.end(),[&](int a,int b){int da=abs(a-base),db=abs(b-base); if(da!=db) return da<db; return a<b;});
414
+ }
415
+ long long bestA=LLONG_MAX; int bestW=0,bestH=0; R bestR; bool hasBestmine=false;
416
+ auto t0=chrono::steady_clock::now();
417
+ const double TL=1980.0;
418
+ double avg=250.0; int cnt=0;
419
+
420
+ // Prepare multiple orderings
421
+ vector<vector<int>> base_orders;
422
+ base_orders.push_back(ord_asc_mindim());
423
+ base_orders.push_back(ord_desc_area());
424
+ base_orders.push_back(ord_desc_maxdim());
425
+ base_orders.push_back(ord_desc_bbox());
426
+ base_orders.push_back(ord_flexibility());
427
+
428
+ bool useGapPacker = (S < 2500); // Use gap-filling for small inputs
429
+ auto doPack = [&](int W, const vector<int>& order, RNG& rng, bool randtie) -> R {
430
+ if(useGapPacker) return pack_gap(W, order, rng, randtie);
431
+ return pack(W, order, rng, randtie);
432
+ };
433
+
434
+ // Track best ordering index per width for perturbation
435
+ int bestOrderIdx = 0;
436
+
437
+ for(int wi=0;wi<(int)Ws.size();wi++){
438
+ auto now=chrono::steady_clock::now();
439
+ double used_time=chrono::duration<double,milli>(now-t0).count();
440
+ if(used_time+avg*1.3>TL) break;
441
+ int W=Ws[wi];
442
+
443
+ // Try each base ordering
444
+ for(int oi=0;oi<(int)base_orders.size();oi++){
445
+ now=chrono::steady_clock::now();
446
+ double used2=chrono::duration<double,milli>(now-t0).count();
447
+ if(used2+avg*1.15>TL) break;
448
+ bool randtie=(oi>=1);
449
+ auto t1=chrono::steady_clock::now();
450
+ R r=doPack(W,base_orders[oi],rng,randtie);
451
+ auto t2=chrono::steady_clock::now();
452
+ double dt=chrono::duration<double,milli>(t2-t1).count();
453
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
454
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
455
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
456
+ bestOrderIdx=oi;
457
+ }
458
+ }
459
+
460
+ // Perturbation of best ordering + random orderings
461
+ int nswaps = max(1, n/20);
462
+ for(int ri=0;ri<4;ri++){
463
+ now=chrono::steady_clock::now();
464
+ double used2=chrono::duration<double,milli>(now-t0).count();
465
+ if(used2+avg*1.15>TL) break;
466
+ auto t1=chrono::steady_clock::now();
467
+ vector<int> order;
468
+ if(ri < 2) order = ord_perturb(base_orders[bestOrderIdx], nswaps);
469
+ else order = ord_random();
470
+ R r=doPack(W,order,rng,true);
471
+ auto t2=chrono::steady_clock::now();
472
+ double dt=chrono::duration<double,milli>(t2-t1).count();
473
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
474
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
475
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
476
+ }
477
+ }
478
+ }
479
+ if(!hasBestmine){
480
+ int W=max(minW,(int)floor(sqrt((double)S)));
481
+ auto o=ord_asc_mindim();
482
+ R r=pack(W,o,rng,false);
483
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
484
+ }
485
+ int maxX=-1;
486
+ for(auto &p:bestR.pl){
487
+ auto &t=ps[p.idx].t[p.ti];
488
+ for(auto &q:t.c){int x=p.x+q.first; if(x>maxX) maxX=x;}
489
+ }
490
+ vector<int> mapx(maxX+1,-1);
491
+ if(maxX>=0){
492
+ vector<char> used(maxX+1,false);
493
+ for(auto &p:bestR.pl){
494
+ auto &t=ps[p.idx].t[p.ti];
495
+ for(auto &q:t.c){used[p.x+q.first]=true;}
496
+ }
497
+ int cur=0;
498
+ for(int x=0;x<=maxX;x++) if(used[x]) mapx[x]=cur++;
499
+ }
500
+ vector<array<int,4>> ans(n,{0,0,0,0});
501
+ for(auto &p:bestR.pl){
502
+ auto &t=ps[p.idx].t[p.ti];
503
+ int bx = (mapx.empty()?p.x:mapx[p.x]);
504
+ int Xi = bx - t.minx;
505
+ int Yi = p.y - t.miny;
506
+ int Ri = (4 - (t.r%4) + 4) % 4;
507
+ int Fi = t.f;
508
+ ans[p.idx]={Xi,Yi,Ri,Fi};
509
+ }
510
+ cout<<bestR.W<<" "<<bestR.H<<"\n";
511
+ for(int i=0;i<n;i++){
512
+ cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<"\n";
513
+ }
514
+ return 0;
515
+ }
docker_space/frontier_cs_0_polyomino_ev2/logs/gen_26.cpp ADDED
@@ -0,0 +1,516 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Gen 1: Multiple orderings + improved width search
3
+ Based on reference.cpp with:
4
+ - 4 ordering strategies (ascending min dim, descending area, descending max dim, random)
5
+ - Each width tries all orderings (time permitting)
6
+ - Better width candidate generation
7
+ */
8
+ #include <bits/stdc++.h>
9
+ using namespace std;
10
+ struct T{int w,h;vector<pair<int,int>> c;vector<int> lo,hi;int r,f,minx,miny;};
11
+ struct P{int id,k;vector<pair<int,int>> b;vector<T> t;int minW=1e9,minH=1e9,minA=1e9;};
12
+ struct Pl{int idx,ti,x,y;};
13
+ struct R{long long A;int W,H;vector<Pl> pl;};
14
+ struct RNG{unsigned long long s;RNG(unsigned long long x){s=x?x:1;}inline unsigned long long nxt(){s^=s<<7;s^=s>>9;return s;}inline int rint(int n){return (int)(nxt()%n);}inline bool coin(){return nxt()&1;}};
15
+ static inline pair<int,int> rotp(pair<int,int> p,int r){if(r==0)return p; if(r==1)return make_pair(-p.second,p.first); if(r==2)return make_pair(-p.first,-p.second); return make_pair(p.second,-p.first);}
16
+ int main(){
17
+ ios::sync_with_stdio(false);
18
+ cin.tie(nullptr);
19
+ int n; if(!(cin>>n)) return 0;
20
+ vector<P> ps(n); long long S=0;
21
+ for(int i=0;i<n;i++){
22
+ int k;cin>>k; ps[i].id=i+1; ps[i].k=k; ps[i].b.resize(k);
23
+ for(int j=0;j<k;j++){int x,y;cin>>x>>y; ps[i].b[j]={x,y};}
24
+ S+=k;
25
+ }
26
+ for(int i=0;i<n;i++){
27
+ auto &p=ps[i]; unordered_set<string> seen; seen.reserve(32);
28
+ for(int rf=0;rf<2;rf++){
29
+ vector<pair<int,int>> src=p.b; if(rf){for(auto &q:src) q.first=-q.first;}
30
+ for(int r=0;r<4;r++){
31
+ vector<pair<int,int>> v=src; for(auto &q:v) q=rotp(q,r);
32
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
33
+ for(auto &q:v){minx=min(minx,q.first);miny=min(miny,q.second);maxx=max(maxx,q.first);maxy=max(maxy,q.second);}
34
+ vector<pair<int,int>> v2=v; for(auto &q:v2){q.first-=minx;q.second-=miny;}
35
+ sort(v2.begin(),v2.end());
36
+ string key; key.reserve(v2.size()*8);
37
+ for(auto &q:v2){key.append(to_string(q.first));key.push_back(',');key.append(to_string(q.second));key.push_back(';');}
38
+ if(seen.insert(key).second){
39
+ T t; t.w=maxx-minx+1; t.h=maxy-miny+1; t.c=v2; t.r=r; t.f=rf; t.minx=minx; t.miny=miny;
40
+ t.lo.assign(t.w,INT_MAX); t.hi.assign(t.w,INT_MIN);
41
+ for(auto &q:v2){int x=q.first,y=q.second; if(t.lo[x]>y) t.lo[x]=y; if(t.hi[x]<y) t.hi[x]=y;}
42
+ p.t.push_back(move(t));
43
+ }
44
+ }
45
+ }
46
+ for(auto &t:p.t){p.minW=min(p.minW,t.w); p.minH=min(p.minH,t.h); p.minA=min(p.minA,t.w*t.h);}
47
+ if(p.t.empty()){T t; t.w=1;t.h=1;t.c={{0,0}};t.lo={0};t.hi={0};t.r=0;t.f=0;t.minx=0;t.miny=0;p.t.push_back(t);p.minW=1;p.minH=1;p.minA=1;}
48
+ }
49
+ vector<int> idx(n); iota(idx.begin(),idx.end(),0);
50
+ unsigned long long seed=((unsigned long long)chrono::high_resolution_clock::now().time_since_epoch().count()) ^ (S<<1) ^ (unsigned long long)(n*1469598103934665603ULL);
51
+ RNG rng(seed);
52
+
53
+ // Multiple ordering strategies
54
+ auto ord_asc_mindim = [&]() {
55
+ vector<int> res = idx;
56
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
57
+ int da = min(ps[a].minW, ps[a].minH);
58
+ int db = min(ps[b].minW, ps[b].minH);
59
+ if (da != db) return da < db;
60
+ if (ps[a].k != ps[b].k) return ps[a].k < ps[b].k;
61
+ return ps[a].id > ps[b].id;
62
+ });
63
+ return res;
64
+ };
65
+ auto ord_desc_area = [&]() {
66
+ vector<int> res = idx;
67
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
68
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
69
+ int da = min(ps[a].minW, ps[a].minH);
70
+ int db = min(ps[b].minW, ps[b].minH);
71
+ if (da != db) return da > db;
72
+ return ps[a].id < ps[b].id;
73
+ });
74
+ return res;
75
+ };
76
+ auto ord_desc_maxdim = [&]() {
77
+ vector<int> res = idx;
78
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
79
+ int da = max(ps[a].minW, ps[a].minH);
80
+ int db = max(ps[b].minW, ps[b].minH);
81
+ if (da != db) return da > db;
82
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
83
+ return ps[a].id < ps[b].id;
84
+ });
85
+ return res;
86
+ };
87
+ auto ord_desc_bbox = [&]() {
88
+ vector<int> res = idx;
89
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
90
+ if (ps[a].minA != ps[b].minA) return ps[a].minA > ps[b].minA;
91
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
92
+ return ps[a].id < ps[b].id;
93
+ });
94
+ return res;
95
+ };
96
+ auto ord_random = [&]() {
97
+ vector<int> res = idx;
98
+ for(int i=n-1;i>0;i--){
99
+ int j=rng.rint(i+1);
100
+ swap(res[i],res[j]);
101
+ }
102
+ return res;
103
+ };
104
+ // Perturb a given ordering by making random swaps
105
+ auto ord_perturb = [&](const vector<int>& base_ord, int nswaps) {
106
+ vector<int> res = base_ord;
107
+ for(int i=0;i<nswaps;i++){
108
+ int a=rng.rint(n), b=rng.rint(n);
109
+ swap(res[a],res[b]);
110
+ }
111
+ return res;
112
+ };
113
+ // Sort by flexibility (fewer variants first = harder to place)
114
+ auto ord_flexibility = [&]() {
115
+ vector<int> res = idx;
116
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
117
+ int va=(int)ps[a].t.size(), vb=(int)ps[b].t.size();
118
+ if(va!=vb) return va<vb;
119
+ if(ps[a].k!=ps[b].k) return ps[a].k>ps[b].k;
120
+ return ps[a].id<ps[b].id;
121
+ });
122
+ return res;
123
+ };
124
+
125
+ auto pack=[&](int W,const vector<int>& o0,RNG &rng,bool randtie){
126
+ vector<int> h(W,-1);
127
+ long long g=-1;
128
+ vector<Pl> pl; pl.reserve(o0.size());
129
+ vector<int> o=o0;
130
+ int t=0,nm=(int)o.size();
131
+ bool big=S>7000;
132
+ int maxBound=max(1,n/4);
133
+ int expLIM=min(maxBound,(int)(350000/max(1LL,S-3500)));
134
+ int dynLIM=big?expLIM:maxBound;
135
+ auto tStart=chrono::steady_clock::now();
136
+ auto batchStart=tStart;
137
+ long long TLms=big?1900:LLONG_MAX/4;
138
+ int stepCnt=0;
139
+ while(t<nm){
140
+ // Increase lookahead for early pieces (they have most impact)
141
+ int earlyBoost = (t < nm/10) ? min(3, max(1, maxBound/dynLIM)) : 1;
142
+ int limCnt=max(1,dynLIM * earlyBoost);
143
+ int lim=min(nm,t+limCnt);
144
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t; int bestid=-1;
145
+ for(int pos=t;pos<lim;pos++){
146
+ int id=o[pos];
147
+ auto &p=ps[id];
148
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
149
+ for(int ti=0;ti<(int)p.t.size();ti++){
150
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
151
+ for(int x0=0;x0<Rpos;x0++){
152
+ int y0=0;
153
+ for(int j=0;j<tsh.w;j++){
154
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
155
+ }
156
+ int nhbuf[32];
157
+ int l=-1; long long dsum=0;
158
+ for(int j=0;j<tsh.w;j++){
159
+ int nh=h[x0+j];
160
+ if(tsh.hi[j]!=INT_MIN){
161
+ int cand=y0+tsh.hi[j];
162
+ if(nh<cand) nh=cand;
163
+ }
164
+ nhbuf[j]=nh;
165
+ if(nh>l) l=nh;
166
+ }
167
+ for(int j=0;j<tsh.w;j++){
168
+ int inc=nhbuf[j]-h[x0+j];
169
+ if(inc>0) dsum+=inc;
170
+ }
171
+ long long dr=0;
172
+ if(x0>0){
173
+ long long old=llabs((long long)h[x0]-h[x0-1]);
174
+ long long nw=llabs((long long)nhbuf[0]-h[x0-1]);
175
+ dr+=nw-old;
176
+ }
177
+ for(int j=0;j<tsh.w-1;j++){
178
+ long long old=llabs((long long)h[x0+j+1]-h[x0+j]);
179
+ long long nw=llabs((long long)nhbuf[j+1]-nhbuf[j]);
180
+ dr+=nw-old;
181
+ }
182
+ if(x0+tsh.w<W){
183
+ long long old=llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);
184
+ long long nw=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1]);
185
+ dr+=nw-old;
186
+ }
187
+ long long gg=g; if(gg<l) gg=l;
188
+ bool take=false;
189
+ if(gg<bestg2) take=true;
190
+ else if(gg==bestg2){
191
+ if(dsum<bds2) take=true;
192
+ else if(dsum==bds2){
193
+ if(l<bl2) take=true;
194
+ else if(l==bl2){
195
+ if(dr<bdr2) take=true;
196
+ else if(dr==bdr2){
197
+ if(y0<by02) take=true;
198
+ else if(y0==by02){
199
+ if(x0<bx02) take=true;
200
+ else if(x0==bx02 && randtie && rng.coin()) take=true;
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
206
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=y0;bl2=l;bds2=dsum;bdr2=dr;by02=y0;bx02=x0;}
207
+ }
208
+ }
209
+ if(bti2==-1) continue;
210
+ // Use waste = dsum - k for between-piece comparison (accounts for piece size)
211
+ long long waste2 = bds2 - p.k;
212
+ bool take=false;
213
+ if(bestg2<bestg) take=true;
214
+ else if(bestg2==bestg){
215
+ if(waste2<bds) take=true;
216
+ else if(waste2==bds){
217
+ if(bl2<bl) take=true;
218
+ else if(bl2==bl){
219
+ if(bdr2<bdr) take=true;
220
+ else if(bdr2==bdr){
221
+ if(by02<by0) take=true;
222
+ else if(by02==by0){
223
+ if(bx02<bx0) take=true;
224
+ else if(bx02==bx0 && randtie && rng.coin()) take=true;
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
231
+ }
232
+ if(bti==-1){t++;stepCnt++;if(big&&stepCnt==5){auto now=chrono::steady_clock::now(); auto elapsed=chrono::duration<double,milli>(now-tStart).count(); auto batch=chrono::duration<double,milli>(now-batchStart).count(); double remT=max(0.0,TLms-elapsed); int remSteps=max(1,nm-t); double budget=remT*5.0/remSteps; if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1); batchStart=now; stepCnt=0;} continue;}
233
+ auto &tsh=ps[bestid].t[bti];
234
+ for(int j=0;j<tsh.w;j++){
235
+ int nh=h[bx+j];
236
+ if(tsh.hi[j]!=INT_MIN){
237
+ int cand=by+tsh.hi[j];
238
+ if(nh<cand) nh=cand;
239
+ }
240
+ h[bx+j]=nh;
241
+ }
242
+ if(g<bl) g=bl;
243
+ pl.push_back({bestid,bti,bx,by});
244
+ if(bestpos!=t) swap(o[t],o[bestpos]);
245
+ t++;
246
+ stepCnt++;
247
+ if(big&&stepCnt==5){
248
+ auto now=chrono::steady_clock::now();
249
+ auto elapsed=chrono::duration<double,milli>(now-tStart).count();
250
+ auto batch=chrono::duration<double,milli>(now-batchStart).count();
251
+ double remT=max(0.0,TLms-elapsed);
252
+ int remSteps=max(1,nm-t);
253
+ double budget=remT*5.0/remSteps;
254
+ if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
255
+ batchStart=now;
256
+ stepCnt=0;
257
+ }
258
+ }
259
+ int H=(int)g+1;
260
+ int maxX=-1;
261
+ for(auto &pp:pl){
262
+ auto &t=ps[pp.idx].t[pp.ti];
263
+ for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}
264
+ }
265
+ int Wused=0;
266
+ if(maxX>=0){
267
+ vector<char> used(maxX+1,false);
268
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}}
269
+ for(int x=0;x<=maxX;x++) if(used[x]) Wused++;
270
+ }
271
+ int Wfinal=max(0,Wused);
272
+ long long A=1LL*H*max(1,Wfinal);
273
+ return R{A,max(1,Wfinal),H,move(pl)};
274
+ };
275
+ // Gap-filling pack for small inputs - tries positions below skyline using bitmap
276
+ auto pack_gap=[&](int W,const vector<int>& o0,RNG &rng,bool randtie) -> R {
277
+ int maxHg=(int)(S/max(1,W)+W+50);
278
+ vector<vector<bool>> grid(W, vector<bool>(maxHg, false));
279
+ vector<int> h(W,-1);
280
+ long long g=-1;
281
+ vector<Pl> pl; pl.reserve(o0.size());
282
+ vector<int> o=o0;
283
+ int t2=0,nm=(int)o.size();
284
+ int maxBound=max(1,n/4);
285
+ int dynLIM=maxBound;
286
+ bool gapEnabled=true;
287
+ while(t2<nm){
288
+ int earlyBoost=(t2<nm/10)?min(3,max(1,maxBound/dynLIM)):1;
289
+ int limCnt=max(1,dynLIM*earlyBoost);
290
+ int lim=min(nm,t2+limCnt);
291
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t2; int bestid=-1;
292
+ for(int pos=t2;pos<lim;pos++){
293
+ int id=o[pos];
294
+ auto &p=ps[id];
295
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
296
+ for(int ti=0;ti<(int)p.t.size();ti++){
297
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
298
+ for(int x0=0;x0<Rpos;x0++){
299
+ // Skyline placement
300
+ int y0=0;
301
+ for(int j=0;j<tsh.w;j++){
302
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
303
+ }
304
+ // Also try gap positions (scan up to 10 rows below skyline)
305
+ int gapY=-1;
306
+ if(gapEnabled && y0>0){
307
+ int sd=min(y0,3); // Only check 3 rows below skyline
308
+ for(int gy=max(0,y0-sd);gy<y0;gy++){
309
+ bool ok=true;
310
+ for(auto &q:tsh.c){
311
+ int gx=x0+q.first,gcy=gy+q.second;
312
+ if(gcy<0||gcy>=maxHg||grid[gx][gcy]){ok=false;break;}
313
+ }
314
+ if(ok){gapY=gy;break;}
315
+ }
316
+ }
317
+ // Evaluate both positions
318
+ for(int pass=0;pass<(gapY>=0?2:1);pass++){
319
+ int yy=(pass==0)?y0:gapY;
320
+ int nhbuf[32];
321
+ int l=-1; long long dsum=0;
322
+ for(int j=0;j<tsh.w;j++){
323
+ int nh=h[x0+j];
324
+ if(tsh.hi[j]!=INT_MIN){int cand=yy+tsh.hi[j]; if(nh<cand) nh=cand;}
325
+ nhbuf[j]=nh; if(nh>l) l=nh;
326
+ }
327
+ for(int j=0;j<tsh.w;j++){int inc=nhbuf[j]-h[x0+j]; if(inc>0) dsum+=inc;}
328
+ long long dr=0;
329
+ if(x0>0){dr+=llabs((long long)nhbuf[0]-h[x0-1])-llabs((long long)h[x0]-h[x0-1]);}
330
+ for(int j=0;j<tsh.w-1;j++){dr+=llabs((long long)nhbuf[j+1]-nhbuf[j])-llabs((long long)h[x0+j+1]-h[x0+j]);}
331
+ if(x0+tsh.w<W){dr+=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1])-llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);}
332
+ long long gg=g; if(gg<l) gg=l;
333
+ bool take=false;
334
+ if(gg<bestg2) take=true;
335
+ else if(gg==bestg2){
336
+ if(dsum<bds2) take=true;
337
+ else if(dsum==bds2){if(l<bl2) take=true;
338
+ else if(l==bl2){if(dr<bdr2) take=true;
339
+ else if(dr==bdr2){if(yy<by02) take=true;
340
+ else if(yy==by02){if(x0<bx02) take=true;
341
+ else if(x0==bx02&&randtie&&rng.coin()) take=true;}}}}
342
+ }
343
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=yy;bl2=l;bds2=dsum;bdr2=dr;by02=yy;bx02=x0;}
344
+ }
345
+ }
346
+ }
347
+ if(bti2==-1) continue;
348
+ long long waste2=bds2-p.k;
349
+ bool take=false;
350
+ if(bestg2<bestg) take=true;
351
+ else if(bestg2==bestg){if(waste2<bds) take=true;
352
+ else if(waste2==bds){if(bl2<bl) take=true;
353
+ else if(bl2==bl){if(bdr2<bdr) take=true;
354
+ else if(bdr2==bdr){if(by02<by0) take=true;
355
+ else if(by02==by0){if(bx02<bx0) take=true;
356
+ else if(bx02==bx0&&randtie&&rng.coin()) take=true;}}}}}
357
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
358
+ }
359
+ if(bti==-1){t2++;continue;}
360
+ auto &tsh=ps[bestid].t[bti];
361
+ for(int j=0;j<tsh.w;j++){
362
+ int nh=h[bx+j];
363
+ if(tsh.hi[j]!=INT_MIN){int cand=by+tsh.hi[j]; if(nh<cand) nh=cand;}
364
+ h[bx+j]=nh;
365
+ }
366
+ for(auto &q:tsh.c){int gx=bx+q.first,gy=by+q.second; if(gx>=0&&gx<W&&gy>=0&&gy<maxHg) grid[gx][gy]=true;}
367
+ if(g<bl) g=bl;
368
+ pl.push_back({bestid,bti,bx,by});
369
+ if(bestpos!=t2) swap(o[t2],o[bestpos]);
370
+ t2++;
371
+ }
372
+ if((int)pl.size() < nm){
373
+ // Not all pieces placed - return failure
374
+ return R{LLONG_MAX, W, 0, {}};
375
+ }
376
+ int H=(int)g+1;
377
+ int maxX=-1;
378
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}}
379
+ int Wused=0;
380
+ if(maxX>=0){vector<char> used(maxX+1,false); for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}} for(int x=0;x<=maxX;x++) if(used[x]) Wused++;}
381
+ int Wfinal=max(0,Wused);
382
+ long long A=1LL*H*max(1,Wfinal);
383
+ return R{A,max(1,Wfinal),H,move(pl)};
384
+ };
385
+ int minW=0; for(auto &p:ps) minW=max(minW,p.minW);
386
+
387
+ // Improved width estimation
388
+ double factor;
389
+ if (S < 1000) factor = 0.4;
390
+ else if (S < 3000) factor = 0.5;
391
+ else if (S < 10000) factor = 0.27;
392
+ else if (S < 30000) factor = 0.08;
393
+ else factor = 0.01;
394
+
395
+ int base = max(minW, (int)floor(sqrt((double)S * factor)));
396
+ vector<int> Ws;
397
+ {
398
+ unordered_set<int> used; used.reserve(512);
399
+ auto addW=[&](int w){if(w<minW) w=minW; if(used.insert(w).second) Ws.push_back(w);};
400
+ addW(base);
401
+ int span=min(96,max(20,base/2));
402
+ for(int d=1;d<=span;d++){addW(base-d); addW(base+d);}
403
+ addW(minW);
404
+ addW((int)max<long long>(minW,(S+base-1)/base));
405
+ for(int m=2;m<=6;m++){addW(base*m/3); addW((int)max<long long>(minW,S/((base*m/3)?(base*m/3):1)));}
406
+ // Add sqrt(S) based widths for more square-like rectangles
407
+ int sqrtS = max(minW, (int)floor(sqrt((double)S)));
408
+ addW(sqrtS);
409
+ addW(sqrtS+1);
410
+ addW(sqrtS-1);
411
+ addW(sqrtS*2/3);
412
+ addW(sqrtS/2);
413
+ sort(Ws.begin(),Ws.end(),[&](int a,int b){int da=abs(a-base),db=abs(b-base); if(da!=db) return da<db; return a<b;});
414
+ }
415
+ long long bestA=LLONG_MAX; int bestW=0,bestH=0; R bestR; bool hasBestmine=false;
416
+ auto t0=chrono::steady_clock::now();
417
+ const double TL=1980.0;
418
+ double avg=250.0; int cnt=0;
419
+
420
+ // Prepare orderings - fewer for gap packer (slower per call)
421
+ bool useGapPacker = (S < 2500);
422
+ vector<vector<int>> base_orders;
423
+ base_orders.push_back(ord_asc_mindim());
424
+ base_orders.push_back(ord_desc_area());
425
+ if(!useGapPacker){
426
+ base_orders.push_back(ord_desc_maxdim());
427
+ base_orders.push_back(ord_desc_bbox());
428
+ }
429
+ base_orders.push_back(ord_flexibility());
430
+ auto doPack = [&](int W, const vector<int>& order, RNG& rng, bool randtie) -> R {
431
+ if(useGapPacker) return pack_gap(W, order, rng, randtie);
432
+ return pack(W, order, rng, randtie);
433
+ };
434
+
435
+ // Track best ordering index per width for perturbation
436
+ int bestOrderIdx = 0;
437
+
438
+ for(int wi=0;wi<(int)Ws.size();wi++){
439
+ auto now=chrono::steady_clock::now();
440
+ double used_time=chrono::duration<double,milli>(now-t0).count();
441
+ if(used_time+avg*1.3>TL) break;
442
+ int W=Ws[wi];
443
+
444
+ // Try each base ordering
445
+ for(int oi=0;oi<(int)base_orders.size();oi++){
446
+ now=chrono::steady_clock::now();
447
+ double used2=chrono::duration<double,milli>(now-t0).count();
448
+ if(used2+avg*1.15>TL) break;
449
+ bool randtie=(oi>=1);
450
+ auto t1=chrono::steady_clock::now();
451
+ R r=doPack(W,base_orders[oi],rng,randtie);
452
+ auto t2=chrono::steady_clock::now();
453
+ double dt=chrono::duration<double,milli>(t2-t1).count();
454
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
455
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
456
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
457
+ bestOrderIdx=oi;
458
+ }
459
+ }
460
+
461
+ // Perturbation of best ordering + random orderings
462
+ int nswaps = max(1, n/20);
463
+ for(int ri=0;ri<4;ri++){
464
+ now=chrono::steady_clock::now();
465
+ double used2=chrono::duration<double,milli>(now-t0).count();
466
+ if(used2+avg*1.15>TL) break;
467
+ auto t1=chrono::steady_clock::now();
468
+ vector<int> order;
469
+ if(ri < 2) order = ord_perturb(base_orders[bestOrderIdx], nswaps);
470
+ else order = ord_random();
471
+ R r=doPack(W,order,rng,true);
472
+ auto t2=chrono::steady_clock::now();
473
+ double dt=chrono::duration<double,milli>(t2-t1).count();
474
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
475
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
476
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
477
+ }
478
+ }
479
+ }
480
+ if(!hasBestmine){
481
+ int W=max(minW,(int)floor(sqrt((double)S)));
482
+ auto o=ord_asc_mindim();
483
+ R r=pack(W,o,rng,false);
484
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
485
+ }
486
+ int maxX=-1;
487
+ for(auto &p:bestR.pl){
488
+ auto &t=ps[p.idx].t[p.ti];
489
+ for(auto &q:t.c){int x=p.x+q.first; if(x>maxX) maxX=x;}
490
+ }
491
+ vector<int> mapx(maxX+1,-1);
492
+ if(maxX>=0){
493
+ vector<char> used(maxX+1,false);
494
+ for(auto &p:bestR.pl){
495
+ auto &t=ps[p.idx].t[p.ti];
496
+ for(auto &q:t.c){used[p.x+q.first]=true;}
497
+ }
498
+ int cur=0;
499
+ for(int x=0;x<=maxX;x++) if(used[x]) mapx[x]=cur++;
500
+ }
501
+ vector<array<int,4>> ans(n,{0,0,0,0});
502
+ for(auto &p:bestR.pl){
503
+ auto &t=ps[p.idx].t[p.ti];
504
+ int bx = (mapx.empty()?p.x:mapx[p.x]);
505
+ int Xi = bx - t.minx;
506
+ int Yi = p.y - t.miny;
507
+ int Ri = (4 - (t.r%4) + 4) % 4;
508
+ int Fi = t.f;
509
+ ans[p.idx]={Xi,Yi,Ri,Fi};
510
+ }
511
+ cout<<bestR.W<<" "<<bestR.H<<"\n";
512
+ for(int i=0;i<n;i++){
513
+ cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<"\n";
514
+ }
515
+ return 0;
516
+ }
docker_space/frontier_cs_0_polyomino_ev2/logs/gen_27.cpp ADDED
@@ -0,0 +1,517 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Gen 1: Multiple orderings + improved width search
3
+ Based on reference.cpp with:
4
+ - 4 ordering strategies (ascending min dim, descending area, descending max dim, random)
5
+ - Each width tries all orderings (time permitting)
6
+ - Better width candidate generation
7
+ */
8
+ #include <bits/stdc++.h>
9
+ using namespace std;
10
+ struct T{int w,h;vector<pair<int,int>> c;vector<int> lo,hi;int r,f,minx,miny;};
11
+ struct P{int id,k;vector<pair<int,int>> b;vector<T> t;int minW=1e9,minH=1e9,minA=1e9;};
12
+ struct Pl{int idx,ti,x,y;};
13
+ struct R{long long A;int W,H;vector<Pl> pl;};
14
+ struct RNG{unsigned long long s;RNG(unsigned long long x){s=x?x:1;}inline unsigned long long nxt(){s^=s<<7;s^=s>>9;return s;}inline int rint(int n){return (int)(nxt()%n);}inline bool coin(){return nxt()&1;}};
15
+ static inline pair<int,int> rotp(pair<int,int> p,int r){if(r==0)return p; if(r==1)return make_pair(-p.second,p.first); if(r==2)return make_pair(-p.first,-p.second); return make_pair(p.second,-p.first);}
16
+ int main(){
17
+ ios::sync_with_stdio(false);
18
+ cin.tie(nullptr);
19
+ int n; if(!(cin>>n)) return 0;
20
+ vector<P> ps(n); long long S=0;
21
+ for(int i=0;i<n;i++){
22
+ int k;cin>>k; ps[i].id=i+1; ps[i].k=k; ps[i].b.resize(k);
23
+ for(int j=0;j<k;j++){int x,y;cin>>x>>y; ps[i].b[j]={x,y};}
24
+ S+=k;
25
+ }
26
+ for(int i=0;i<n;i++){
27
+ auto &p=ps[i]; unordered_set<string> seen; seen.reserve(32);
28
+ for(int rf=0;rf<2;rf++){
29
+ vector<pair<int,int>> src=p.b; if(rf){for(auto &q:src) q.first=-q.first;}
30
+ for(int r=0;r<4;r++){
31
+ vector<pair<int,int>> v=src; for(auto &q:v) q=rotp(q,r);
32
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
33
+ for(auto &q:v){minx=min(minx,q.first);miny=min(miny,q.second);maxx=max(maxx,q.first);maxy=max(maxy,q.second);}
34
+ vector<pair<int,int>> v2=v; for(auto &q:v2){q.first-=minx;q.second-=miny;}
35
+ sort(v2.begin(),v2.end());
36
+ string key; key.reserve(v2.size()*8);
37
+ for(auto &q:v2){key.append(to_string(q.first));key.push_back(',');key.append(to_string(q.second));key.push_back(';');}
38
+ if(seen.insert(key).second){
39
+ T t; t.w=maxx-minx+1; t.h=maxy-miny+1; t.c=v2; t.r=r; t.f=rf; t.minx=minx; t.miny=miny;
40
+ t.lo.assign(t.w,INT_MAX); t.hi.assign(t.w,INT_MIN);
41
+ for(auto &q:v2){int x=q.first,y=q.second; if(t.lo[x]>y) t.lo[x]=y; if(t.hi[x]<y) t.hi[x]=y;}
42
+ p.t.push_back(move(t));
43
+ }
44
+ }
45
+ }
46
+ for(auto &t:p.t){p.minW=min(p.minW,t.w); p.minH=min(p.minH,t.h); p.minA=min(p.minA,t.w*t.h);}
47
+ if(p.t.empty()){T t; t.w=1;t.h=1;t.c={{0,0}};t.lo={0};t.hi={0};t.r=0;t.f=0;t.minx=0;t.miny=0;p.t.push_back(t);p.minW=1;p.minH=1;p.minA=1;}
48
+ }
49
+ vector<int> idx(n); iota(idx.begin(),idx.end(),0);
50
+ unsigned long long seed=((unsigned long long)chrono::high_resolution_clock::now().time_since_epoch().count()) ^ (S<<1) ^ (unsigned long long)(n*1469598103934665603ULL);
51
+ RNG rng(seed);
52
+
53
+ // Multiple ordering strategies
54
+ auto ord_asc_mindim = [&]() {
55
+ vector<int> res = idx;
56
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
57
+ int da = min(ps[a].minW, ps[a].minH);
58
+ int db = min(ps[b].minW, ps[b].minH);
59
+ if (da != db) return da < db;
60
+ if (ps[a].k != ps[b].k) return ps[a].k < ps[b].k;
61
+ return ps[a].id > ps[b].id;
62
+ });
63
+ return res;
64
+ };
65
+ auto ord_desc_area = [&]() {
66
+ vector<int> res = idx;
67
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
68
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
69
+ int da = min(ps[a].minW, ps[a].minH);
70
+ int db = min(ps[b].minW, ps[b].minH);
71
+ if (da != db) return da > db;
72
+ return ps[a].id < ps[b].id;
73
+ });
74
+ return res;
75
+ };
76
+ auto ord_desc_maxdim = [&]() {
77
+ vector<int> res = idx;
78
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
79
+ int da = max(ps[a].minW, ps[a].minH);
80
+ int db = max(ps[b].minW, ps[b].minH);
81
+ if (da != db) return da > db;
82
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
83
+ return ps[a].id < ps[b].id;
84
+ });
85
+ return res;
86
+ };
87
+ auto ord_desc_bbox = [&]() {
88
+ vector<int> res = idx;
89
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
90
+ if (ps[a].minA != ps[b].minA) return ps[a].minA > ps[b].minA;
91
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
92
+ return ps[a].id < ps[b].id;
93
+ });
94
+ return res;
95
+ };
96
+ auto ord_random = [&]() {
97
+ vector<int> res = idx;
98
+ for(int i=n-1;i>0;i--){
99
+ int j=rng.rint(i+1);
100
+ swap(res[i],res[j]);
101
+ }
102
+ return res;
103
+ };
104
+ // Perturb a given ordering by making random swaps
105
+ auto ord_perturb = [&](const vector<int>& base_ord, int nswaps) {
106
+ vector<int> res = base_ord;
107
+ for(int i=0;i<nswaps;i++){
108
+ int a=rng.rint(n), b=rng.rint(n);
109
+ swap(res[a],res[b]);
110
+ }
111
+ return res;
112
+ };
113
+ // Sort by flexibility (fewer variants first = harder to place)
114
+ auto ord_flexibility = [&]() {
115
+ vector<int> res = idx;
116
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
117
+ int va=(int)ps[a].t.size(), vb=(int)ps[b].t.size();
118
+ if(va!=vb) return va<vb;
119
+ if(ps[a].k!=ps[b].k) return ps[a].k>ps[b].k;
120
+ return ps[a].id<ps[b].id;
121
+ });
122
+ return res;
123
+ };
124
+
125
+ auto pack=[&](int W,const vector<int>& o0,RNG &rng,bool randtie){
126
+ vector<int> h(W,-1);
127
+ long long g=-1;
128
+ vector<Pl> pl; pl.reserve(o0.size());
129
+ vector<int> o=o0;
130
+ int t=0,nm=(int)o.size();
131
+ bool big=S>7000;
132
+ int maxBound=max(1,n/4);
133
+ int expLIM=min(maxBound,(int)(350000/max(1LL,S-3500)));
134
+ int dynLIM=big?expLIM:maxBound;
135
+ auto tStart=chrono::steady_clock::now();
136
+ auto batchStart=tStart;
137
+ long long TLms=big?1900:LLONG_MAX/4;
138
+ int stepCnt=0;
139
+ while(t<nm){
140
+ // Increase lookahead for early pieces (they have most impact)
141
+ int earlyBoost = (t < nm/10) ? min(3, max(1, maxBound/dynLIM)) : 1;
142
+ int limCnt=max(1,dynLIM * earlyBoost);
143
+ int lim=min(nm,t+limCnt);
144
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t; int bestid=-1;
145
+ for(int pos=t;pos<lim;pos++){
146
+ int id=o[pos];
147
+ auto &p=ps[id];
148
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
149
+ for(int ti=0;ti<(int)p.t.size();ti++){
150
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
151
+ for(int x0=0;x0<Rpos;x0++){
152
+ int y0=0;
153
+ for(int j=0;j<tsh.w;j++){
154
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
155
+ }
156
+ int nhbuf[32];
157
+ int l=-1; long long dsum=0;
158
+ for(int j=0;j<tsh.w;j++){
159
+ int nh=h[x0+j];
160
+ if(tsh.hi[j]!=INT_MIN){
161
+ int cand=y0+tsh.hi[j];
162
+ if(nh<cand) nh=cand;
163
+ }
164
+ nhbuf[j]=nh;
165
+ if(nh>l) l=nh;
166
+ }
167
+ for(int j=0;j<tsh.w;j++){
168
+ int inc=nhbuf[j]-h[x0+j];
169
+ if(inc>0) dsum+=inc;
170
+ }
171
+ long long dr=0;
172
+ if(x0>0){
173
+ long long old=llabs((long long)h[x0]-h[x0-1]);
174
+ long long nw=llabs((long long)nhbuf[0]-h[x0-1]);
175
+ dr+=nw-old;
176
+ }
177
+ for(int j=0;j<tsh.w-1;j++){
178
+ long long old=llabs((long long)h[x0+j+1]-h[x0+j]);
179
+ long long nw=llabs((long long)nhbuf[j+1]-nhbuf[j]);
180
+ dr+=nw-old;
181
+ }
182
+ if(x0+tsh.w<W){
183
+ long long old=llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);
184
+ long long nw=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1]);
185
+ dr+=nw-old;
186
+ }
187
+ long long gg=g; if(gg<l) gg=l;
188
+ bool take=false;
189
+ if(gg<bestg2) take=true;
190
+ else if(gg==bestg2){
191
+ if(dsum<bds2) take=true;
192
+ else if(dsum==bds2){
193
+ if(l<bl2) take=true;
194
+ else if(l==bl2){
195
+ if(dr<bdr2) take=true;
196
+ else if(dr==bdr2){
197
+ if(y0<by02) take=true;
198
+ else if(y0==by02){
199
+ if(x0<bx02) take=true;
200
+ else if(x0==bx02 && randtie && rng.coin()) take=true;
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
206
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=y0;bl2=l;bds2=dsum;bdr2=dr;by02=y0;bx02=x0;}
207
+ }
208
+ }
209
+ if(bti2==-1) continue;
210
+ // Use waste = dsum - k for between-piece comparison (accounts for piece size)
211
+ long long waste2 = bds2 - p.k;
212
+ bool take=false;
213
+ if(bestg2<bestg) take=true;
214
+ else if(bestg2==bestg){
215
+ if(waste2<bds) take=true;
216
+ else if(waste2==bds){
217
+ if(bl2<bl) take=true;
218
+ else if(bl2==bl){
219
+ if(bdr2<bdr) take=true;
220
+ else if(bdr2==bdr){
221
+ if(by02<by0) take=true;
222
+ else if(by02==by0){
223
+ if(bx02<bx0) take=true;
224
+ else if(bx02==bx0 && randtie && rng.coin()) take=true;
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
231
+ }
232
+ if(bti==-1){t++;stepCnt++;if(big&&stepCnt==5){auto now=chrono::steady_clock::now(); auto elapsed=chrono::duration<double,milli>(now-tStart).count(); auto batch=chrono::duration<double,milli>(now-batchStart).count(); double remT=max(0.0,TLms-elapsed); int remSteps=max(1,nm-t); double budget=remT*5.0/remSteps; if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1); batchStart=now; stepCnt=0;} continue;}
233
+ auto &tsh=ps[bestid].t[bti];
234
+ for(int j=0;j<tsh.w;j++){
235
+ int nh=h[bx+j];
236
+ if(tsh.hi[j]!=INT_MIN){
237
+ int cand=by+tsh.hi[j];
238
+ if(nh<cand) nh=cand;
239
+ }
240
+ h[bx+j]=nh;
241
+ }
242
+ if(g<bl) g=bl;
243
+ pl.push_back({bestid,bti,bx,by});
244
+ if(bestpos!=t) swap(o[t],o[bestpos]);
245
+ t++;
246
+ stepCnt++;
247
+ if(big&&stepCnt==5){
248
+ auto now=chrono::steady_clock::now();
249
+ auto elapsed=chrono::duration<double,milli>(now-tStart).count();
250
+ auto batch=chrono::duration<double,milli>(now-batchStart).count();
251
+ double remT=max(0.0,TLms-elapsed);
252
+ int remSteps=max(1,nm-t);
253
+ double budget=remT*5.0/remSteps;
254
+ if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
255
+ batchStart=now;
256
+ stepCnt=0;
257
+ }
258
+ }
259
+ int H=(int)g+1;
260
+ int maxX=-1;
261
+ for(auto &pp:pl){
262
+ auto &t=ps[pp.idx].t[pp.ti];
263
+ for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}
264
+ }
265
+ int Wused=0;
266
+ if(maxX>=0){
267
+ vector<char> used(maxX+1,false);
268
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}}
269
+ for(int x=0;x<=maxX;x++) if(used[x]) Wused++;
270
+ }
271
+ int Wfinal=max(0,Wused);
272
+ long long A=1LL*H*max(1,Wfinal);
273
+ return R{A,max(1,Wfinal),H,move(pl)};
274
+ };
275
+ // Gap-filling pack for small inputs - tries positions below skyline using bitmap
276
+ auto pack_gap=[&](int W,const vector<int>& o0,RNG &rng,bool randtie) -> R {
277
+ int maxHg=(int)(S/max(1,W)+W+50);
278
+ vector<vector<bool>> grid(W, vector<bool>(maxHg, false));
279
+ vector<int> h(W,-1);
280
+ long long g=-1;
281
+ vector<Pl> pl; pl.reserve(o0.size());
282
+ vector<int> o=o0;
283
+ int t2=0,nm=(int)o.size();
284
+ int maxBound=max(1,n/4);
285
+ int dynLIM=maxBound;
286
+ bool gapEnabled=true;
287
+ while(t2<nm){
288
+ int earlyBoost=(t2<nm/10)?min(3,max(1,maxBound/dynLIM)):1;
289
+ int limCnt=max(1,dynLIM*earlyBoost);
290
+ int lim=min(nm,t2+limCnt);
291
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t2; int bestid=-1;
292
+ for(int pos=t2;pos<lim;pos++){
293
+ int id=o[pos];
294
+ auto &p=ps[id];
295
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
296
+ for(int ti=0;ti<(int)p.t.size();ti++){
297
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
298
+ for(int x0=0;x0<Rpos;x0++){
299
+ // Skyline placement
300
+ int y0=0;
301
+ for(int j=0;j<tsh.w;j++){
302
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
303
+ }
304
+ // Also try gap positions (scan up to 10 rows below skyline)
305
+ int gapY=-1;
306
+ if(gapEnabled && y0>0){
307
+ int sd=min(y0,3); // Only check 3 rows below skyline
308
+ for(int gy=max(0,y0-sd);gy<y0;gy++){
309
+ bool ok=true;
310
+ for(auto &q:tsh.c){
311
+ int gx=x0+q.first,gcy=gy+q.second;
312
+ if(gcy<0||gcy>=maxHg||grid[gx][gcy]){ok=false;break;}
313
+ }
314
+ if(ok){gapY=gy;break;}
315
+ }
316
+ }
317
+ // Evaluate both positions
318
+ for(int pass=0;pass<(gapY>=0?2:1);pass++){
319
+ int yy=(pass==0)?y0:gapY;
320
+ int nhbuf[32];
321
+ int l=-1; long long dsum=0;
322
+ for(int j=0;j<tsh.w;j++){
323
+ int nh=h[x0+j];
324
+ if(tsh.hi[j]!=INT_MIN){int cand=yy+tsh.hi[j]; if(nh<cand) nh=cand;}
325
+ nhbuf[j]=nh; if(nh>l) l=nh;
326
+ }
327
+ for(int j=0;j<tsh.w;j++){int inc=nhbuf[j]-h[x0+j]; if(inc>0) dsum+=inc;}
328
+ long long dr=0;
329
+ if(x0>0){dr+=llabs((long long)nhbuf[0]-h[x0-1])-llabs((long long)h[x0]-h[x0-1]);}
330
+ for(int j=0;j<tsh.w-1;j++){dr+=llabs((long long)nhbuf[j+1]-nhbuf[j])-llabs((long long)h[x0+j+1]-h[x0+j]);}
331
+ if(x0+tsh.w<W){dr+=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1])-llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);}
332
+ long long gg=g; if(gg<l) gg=l;
333
+ bool take=false;
334
+ if(gg<bestg2) take=true;
335
+ else if(gg==bestg2){
336
+ if(dsum<bds2) take=true;
337
+ else if(dsum==bds2){if(l<bl2) take=true;
338
+ else if(l==bl2){if(dr<bdr2) take=true;
339
+ else if(dr==bdr2){if(yy<by02) take=true;
340
+ else if(yy==by02){if(x0<bx02) take=true;
341
+ else if(x0==bx02&&randtie&&rng.coin()) take=true;}}}}
342
+ }
343
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=yy;bl2=l;bds2=dsum;bdr2=dr;by02=yy;bx02=x0;}
344
+ }
345
+ }
346
+ }
347
+ if(bti2==-1) continue;
348
+ long long waste2=bds2-p.k;
349
+ bool take=false;
350
+ if(bestg2<bestg) take=true;
351
+ else if(bestg2==bestg){if(waste2<bds) take=true;
352
+ else if(waste2==bds){if(bl2<bl) take=true;
353
+ else if(bl2==bl){if(bdr2<bdr) take=true;
354
+ else if(bdr2==bdr){if(by02<by0) take=true;
355
+ else if(by02==by0){if(bx02<bx0) take=true;
356
+ else if(bx02==bx0&&randtie&&rng.coin()) take=true;}}}}}
357
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
358
+ }
359
+ if(bti==-1){t2++;continue;}
360
+ auto &tsh=ps[bestid].t[bti];
361
+ for(int j=0;j<tsh.w;j++){
362
+ int nh=h[bx+j];
363
+ if(tsh.hi[j]!=INT_MIN){int cand=by+tsh.hi[j]; if(nh<cand) nh=cand;}
364
+ h[bx+j]=nh;
365
+ }
366
+ for(auto &q:tsh.c){int gx=bx+q.first,gy=by+q.second; if(gx>=0&&gx<W&&gy>=0&&gy<maxHg) grid[gx][gy]=true;}
367
+ if(g<bl) g=bl;
368
+ pl.push_back({bestid,bti,bx,by});
369
+ if(bestpos!=t2) swap(o[t2],o[bestpos]);
370
+ t2++;
371
+ }
372
+ if((int)pl.size() < nm){
373
+ // Not all pieces placed - return failure
374
+ return R{LLONG_MAX, W, 0, {}};
375
+ }
376
+ int H=(int)g+1;
377
+ int maxX=-1;
378
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}}
379
+ int Wused=0;
380
+ if(maxX>=0){vector<char> used(maxX+1,false); for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}} for(int x=0;x<=maxX;x++) if(used[x]) Wused++;}
381
+ int Wfinal=max(0,Wused);
382
+ long long A=1LL*H*max(1,Wfinal);
383
+ return R{A,max(1,Wfinal),H,move(pl)};
384
+ };
385
+ int minW=0; for(auto &p:ps) minW=max(minW,p.minW);
386
+
387
+ // Improved width estimation
388
+ double factor;
389
+ if (S < 1000) factor = 0.4;
390
+ else if (S < 3000) factor = 0.5;
391
+ else if (S < 10000) factor = 0.27;
392
+ else if (S < 30000) factor = 0.08;
393
+ else factor = 0.01;
394
+
395
+ int base = max(minW, (int)floor(sqrt((double)S * factor)));
396
+ vector<int> Ws;
397
+ {
398
+ unordered_set<int> used; used.reserve(512);
399
+ auto addW=[&](int w){if(w<minW) w=minW; if(used.insert(w).second) Ws.push_back(w);};
400
+ addW(base);
401
+ int span=min(96,max(20,base/2));
402
+ for(int d=1;d<=span;d++){addW(base-d); addW(base+d);}
403
+ addW(minW);
404
+ addW((int)max<long long>(minW,(S+base-1)/base));
405
+ for(int m=2;m<=6;m++){addW(base*m/3); addW((int)max<long long>(minW,S/((base*m/3)?(base*m/3):1)));}
406
+ // Add sqrt(S) based widths for more square-like rectangles
407
+ int sqrtS = max(minW, (int)floor(sqrt((double)S)));
408
+ addW(sqrtS);
409
+ addW(sqrtS+1);
410
+ addW(sqrtS-1);
411
+ addW(sqrtS*2/3);
412
+ addW(sqrtS/2);
413
+ sort(Ws.begin(),Ws.end(),[&](int a,int b){int da=abs(a-base),db=abs(b-base); if(da!=db) return da<db; return a<b;});
414
+ }
415
+ long long bestA=LLONG_MAX; int bestW=0,bestH=0; R bestR; bool hasBestmine=false;
416
+ auto t0=chrono::steady_clock::now();
417
+ const double TL=1980.0;
418
+ double avg=250.0; int cnt=0;
419
+
420
+ // Prepare orderings - fewer for gap packer (slower per call)
421
+ bool useGapPacker = (S < 2500);
422
+ vector<vector<int>> base_orders;
423
+ base_orders.push_back(ord_asc_mindim());
424
+ base_orders.push_back(ord_desc_area());
425
+ if(!useGapPacker){
426
+ base_orders.push_back(ord_desc_maxdim());
427
+ base_orders.push_back(ord_desc_bbox());
428
+ base_orders.push_back(ord_flexibility());
429
+ }
430
+ auto doPack = [&](int W, const vector<int>& order, RNG& rng, bool randtie) -> R {
431
+ if(useGapPacker) return pack_gap(W, order, rng, randtie);
432
+ return pack(W, order, rng, randtie);
433
+ };
434
+
435
+ // Track best ordering index per width for perturbation
436
+ int bestOrderIdx = 0;
437
+
438
+ for(int wi=0;wi<(int)Ws.size();wi++){
439
+ auto now=chrono::steady_clock::now();
440
+ double used_time=chrono::duration<double,milli>(now-t0).count();
441
+ if(used_time+avg*1.3>TL) break;
442
+ int W=Ws[wi];
443
+
444
+ // Try each base ordering
445
+ for(int oi=0;oi<(int)base_orders.size();oi++){
446
+ now=chrono::steady_clock::now();
447
+ double used2=chrono::duration<double,milli>(now-t0).count();
448
+ if(used2+avg*1.15>TL) break;
449
+ bool randtie=(oi>=1);
450
+ auto t1=chrono::steady_clock::now();
451
+ R r=doPack(W,base_orders[oi],rng,randtie);
452
+ auto t2=chrono::steady_clock::now();
453
+ double dt=chrono::duration<double,milli>(t2-t1).count();
454
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
455
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
456
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
457
+ bestOrderIdx=oi;
458
+ }
459
+ }
460
+
461
+ // Perturbation of best ordering + random orderings
462
+ int nswaps = max(1, n/20);
463
+ int maxRandom = useGapPacker ? 2 : 4;
464
+ for(int ri=0;ri<maxRandom;ri++){
465
+ now=chrono::steady_clock::now();
466
+ double used2=chrono::duration<double,milli>(now-t0).count();
467
+ if(used2+avg*1.15>TL) break;
468
+ auto t1=chrono::steady_clock::now();
469
+ vector<int> order;
470
+ if(ri < 2) order = ord_perturb(base_orders[bestOrderIdx], nswaps);
471
+ else order = ord_random();
472
+ R r=doPack(W,order,rng,true);
473
+ auto t2=chrono::steady_clock::now();
474
+ double dt=chrono::duration<double,milli>(t2-t1).count();
475
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
476
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
477
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
478
+ }
479
+ }
480
+ }
481
+ if(!hasBestmine){
482
+ int W=max(minW,(int)floor(sqrt((double)S)));
483
+ auto o=ord_asc_mindim();
484
+ R r=pack(W,o,rng,false);
485
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
486
+ }
487
+ int maxX=-1;
488
+ for(auto &p:bestR.pl){
489
+ auto &t=ps[p.idx].t[p.ti];
490
+ for(auto &q:t.c){int x=p.x+q.first; if(x>maxX) maxX=x;}
491
+ }
492
+ vector<int> mapx(maxX+1,-1);
493
+ if(maxX>=0){
494
+ vector<char> used(maxX+1,false);
495
+ for(auto &p:bestR.pl){
496
+ auto &t=ps[p.idx].t[p.ti];
497
+ for(auto &q:t.c){used[p.x+q.first]=true;}
498
+ }
499
+ int cur=0;
500
+ for(int x=0;x<=maxX;x++) if(used[x]) mapx[x]=cur++;
501
+ }
502
+ vector<array<int,4>> ans(n,{0,0,0,0});
503
+ for(auto &p:bestR.pl){
504
+ auto &t=ps[p.idx].t[p.ti];
505
+ int bx = (mapx.empty()?p.x:mapx[p.x]);
506
+ int Xi = bx - t.minx;
507
+ int Yi = p.y - t.miny;
508
+ int Ri = (4 - (t.r%4) + 4) % 4;
509
+ int Fi = t.f;
510
+ ans[p.idx]={Xi,Yi,Ri,Fi};
511
+ }
512
+ cout<<bestR.W<<" "<<bestR.H<<"\n";
513
+ for(int i=0;i<n;i++){
514
+ cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<"\n";
515
+ }
516
+ return 0;
517
+ }
docker_space/frontier_cs_0_polyomino_ev2/logs/gen_28.cpp ADDED
@@ -0,0 +1,517 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Gen 1: Multiple orderings + improved width search
3
+ Based on reference.cpp with:
4
+ - 4 ordering strategies (ascending min dim, descending area, descending max dim, random)
5
+ - Each width tries all orderings (time permitting)
6
+ - Better width candidate generation
7
+ */
8
+ #include <bits/stdc++.h>
9
+ using namespace std;
10
+ struct T{int w,h;vector<pair<int,int>> c;vector<int> lo,hi;int r,f,minx,miny;};
11
+ struct P{int id,k;vector<pair<int,int>> b;vector<T> t;int minW=1e9,minH=1e9,minA=1e9;};
12
+ struct Pl{int idx,ti,x,y;};
13
+ struct R{long long A;int W,H;vector<Pl> pl;};
14
+ struct RNG{unsigned long long s;RNG(unsigned long long x){s=x?x:1;}inline unsigned long long nxt(){s^=s<<7;s^=s>>9;return s;}inline int rint(int n){return (int)(nxt()%n);}inline bool coin(){return nxt()&1;}};
15
+ static inline pair<int,int> rotp(pair<int,int> p,int r){if(r==0)return p; if(r==1)return make_pair(-p.second,p.first); if(r==2)return make_pair(-p.first,-p.second); return make_pair(p.second,-p.first);}
16
+ int main(){
17
+ ios::sync_with_stdio(false);
18
+ cin.tie(nullptr);
19
+ int n; if(!(cin>>n)) return 0;
20
+ vector<P> ps(n); long long S=0;
21
+ for(int i=0;i<n;i++){
22
+ int k;cin>>k; ps[i].id=i+1; ps[i].k=k; ps[i].b.resize(k);
23
+ for(int j=0;j<k;j++){int x,y;cin>>x>>y; ps[i].b[j]={x,y};}
24
+ S+=k;
25
+ }
26
+ for(int i=0;i<n;i++){
27
+ auto &p=ps[i]; unordered_set<string> seen; seen.reserve(32);
28
+ for(int rf=0;rf<2;rf++){
29
+ vector<pair<int,int>> src=p.b; if(rf){for(auto &q:src) q.first=-q.first;}
30
+ for(int r=0;r<4;r++){
31
+ vector<pair<int,int>> v=src; for(auto &q:v) q=rotp(q,r);
32
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
33
+ for(auto &q:v){minx=min(minx,q.first);miny=min(miny,q.second);maxx=max(maxx,q.first);maxy=max(maxy,q.second);}
34
+ vector<pair<int,int>> v2=v; for(auto &q:v2){q.first-=minx;q.second-=miny;}
35
+ sort(v2.begin(),v2.end());
36
+ string key; key.reserve(v2.size()*8);
37
+ for(auto &q:v2){key.append(to_string(q.first));key.push_back(',');key.append(to_string(q.second));key.push_back(';');}
38
+ if(seen.insert(key).second){
39
+ T t; t.w=maxx-minx+1; t.h=maxy-miny+1; t.c=v2; t.r=r; t.f=rf; t.minx=minx; t.miny=miny;
40
+ t.lo.assign(t.w,INT_MAX); t.hi.assign(t.w,INT_MIN);
41
+ for(auto &q:v2){int x=q.first,y=q.second; if(t.lo[x]>y) t.lo[x]=y; if(t.hi[x]<y) t.hi[x]=y;}
42
+ p.t.push_back(move(t));
43
+ }
44
+ }
45
+ }
46
+ for(auto &t:p.t){p.minW=min(p.minW,t.w); p.minH=min(p.minH,t.h); p.minA=min(p.minA,t.w*t.h);}
47
+ if(p.t.empty()){T t; t.w=1;t.h=1;t.c={{0,0}};t.lo={0};t.hi={0};t.r=0;t.f=0;t.minx=0;t.miny=0;p.t.push_back(t);p.minW=1;p.minH=1;p.minA=1;}
48
+ }
49
+ vector<int> idx(n); iota(idx.begin(),idx.end(),0);
50
+ unsigned long long seed=((unsigned long long)chrono::high_resolution_clock::now().time_since_epoch().count()) ^ (S<<1) ^ (unsigned long long)(n*1469598103934665603ULL);
51
+ RNG rng(seed);
52
+
53
+ // Multiple ordering strategies
54
+ auto ord_asc_mindim = [&]() {
55
+ vector<int> res = idx;
56
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
57
+ int da = min(ps[a].minW, ps[a].minH);
58
+ int db = min(ps[b].minW, ps[b].minH);
59
+ if (da != db) return da < db;
60
+ if (ps[a].k != ps[b].k) return ps[a].k < ps[b].k;
61
+ return ps[a].id > ps[b].id;
62
+ });
63
+ return res;
64
+ };
65
+ auto ord_desc_area = [&]() {
66
+ vector<int> res = idx;
67
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
68
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
69
+ int da = min(ps[a].minW, ps[a].minH);
70
+ int db = min(ps[b].minW, ps[b].minH);
71
+ if (da != db) return da > db;
72
+ return ps[a].id < ps[b].id;
73
+ });
74
+ return res;
75
+ };
76
+ auto ord_desc_maxdim = [&]() {
77
+ vector<int> res = idx;
78
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
79
+ int da = max(ps[a].minW, ps[a].minH);
80
+ int db = max(ps[b].minW, ps[b].minH);
81
+ if (da != db) return da > db;
82
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
83
+ return ps[a].id < ps[b].id;
84
+ });
85
+ return res;
86
+ };
87
+ auto ord_desc_bbox = [&]() {
88
+ vector<int> res = idx;
89
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
90
+ if (ps[a].minA != ps[b].minA) return ps[a].minA > ps[b].minA;
91
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
92
+ return ps[a].id < ps[b].id;
93
+ });
94
+ return res;
95
+ };
96
+ auto ord_random = [&]() {
97
+ vector<int> res = idx;
98
+ for(int i=n-1;i>0;i--){
99
+ int j=rng.rint(i+1);
100
+ swap(res[i],res[j]);
101
+ }
102
+ return res;
103
+ };
104
+ // Perturb a given ordering by making random swaps
105
+ auto ord_perturb = [&](const vector<int>& base_ord, int nswaps) {
106
+ vector<int> res = base_ord;
107
+ for(int i=0;i<nswaps;i++){
108
+ int a=rng.rint(n), b=rng.rint(n);
109
+ swap(res[a],res[b]);
110
+ }
111
+ return res;
112
+ };
113
+ // Sort by flexibility (fewer variants first = harder to place)
114
+ auto ord_flexibility = [&]() {
115
+ vector<int> res = idx;
116
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
117
+ int va=(int)ps[a].t.size(), vb=(int)ps[b].t.size();
118
+ if(va!=vb) return va<vb;
119
+ if(ps[a].k!=ps[b].k) return ps[a].k>ps[b].k;
120
+ return ps[a].id<ps[b].id;
121
+ });
122
+ return res;
123
+ };
124
+
125
+ auto pack=[&](int W,const vector<int>& o0,RNG &rng,bool randtie){
126
+ vector<int> h(W,-1);
127
+ long long g=-1;
128
+ vector<Pl> pl; pl.reserve(o0.size());
129
+ vector<int> o=o0;
130
+ int t=0,nm=(int)o.size();
131
+ bool big=S>7000;
132
+ int maxBound=max(1,n/4);
133
+ int expLIM=min(maxBound,(int)(350000/max(1LL,S-3500)));
134
+ int dynLIM=big?expLIM:maxBound;
135
+ auto tStart=chrono::steady_clock::now();
136
+ auto batchStart=tStart;
137
+ long long TLms=big?1900:LLONG_MAX/4;
138
+ int stepCnt=0;
139
+ while(t<nm){
140
+ // Increase lookahead for early pieces (they have most impact)
141
+ int earlyBoost = (t < nm/10) ? min(3, max(1, maxBound/dynLIM)) : 1;
142
+ int limCnt=max(1,dynLIM * earlyBoost);
143
+ int lim=min(nm,t+limCnt);
144
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t; int bestid=-1;
145
+ for(int pos=t;pos<lim;pos++){
146
+ int id=o[pos];
147
+ auto &p=ps[id];
148
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
149
+ for(int ti=0;ti<(int)p.t.size();ti++){
150
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
151
+ for(int x0=0;x0<Rpos;x0++){
152
+ int y0=0;
153
+ for(int j=0;j<tsh.w;j++){
154
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
155
+ }
156
+ int nhbuf[32];
157
+ int l=-1; long long dsum=0;
158
+ for(int j=0;j<tsh.w;j++){
159
+ int nh=h[x0+j];
160
+ if(tsh.hi[j]!=INT_MIN){
161
+ int cand=y0+tsh.hi[j];
162
+ if(nh<cand) nh=cand;
163
+ }
164
+ nhbuf[j]=nh;
165
+ if(nh>l) l=nh;
166
+ }
167
+ for(int j=0;j<tsh.w;j++){
168
+ int inc=nhbuf[j]-h[x0+j];
169
+ if(inc>0) dsum+=inc;
170
+ }
171
+ long long dr=0;
172
+ if(x0>0){
173
+ long long old=llabs((long long)h[x0]-h[x0-1]);
174
+ long long nw=llabs((long long)nhbuf[0]-h[x0-1]);
175
+ dr+=nw-old;
176
+ }
177
+ for(int j=0;j<tsh.w-1;j++){
178
+ long long old=llabs((long long)h[x0+j+1]-h[x0+j]);
179
+ long long nw=llabs((long long)nhbuf[j+1]-nhbuf[j]);
180
+ dr+=nw-old;
181
+ }
182
+ if(x0+tsh.w<W){
183
+ long long old=llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);
184
+ long long nw=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1]);
185
+ dr+=nw-old;
186
+ }
187
+ long long gg=g; if(gg<l) gg=l;
188
+ bool take=false;
189
+ if(gg<bestg2) take=true;
190
+ else if(gg==bestg2){
191
+ if(dsum<bds2) take=true;
192
+ else if(dsum==bds2){
193
+ if(l<bl2) take=true;
194
+ else if(l==bl2){
195
+ if(dr<bdr2) take=true;
196
+ else if(dr==bdr2){
197
+ if(y0<by02) take=true;
198
+ else if(y0==by02){
199
+ if(x0<bx02) take=true;
200
+ else if(x0==bx02 && randtie && rng.coin()) take=true;
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
206
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=y0;bl2=l;bds2=dsum;bdr2=dr;by02=y0;bx02=x0;}
207
+ }
208
+ }
209
+ if(bti2==-1) continue;
210
+ // Use waste = dsum - k for between-piece comparison (accounts for piece size)
211
+ long long waste2 = bds2 - p.k;
212
+ bool take=false;
213
+ if(bestg2<bestg) take=true;
214
+ else if(bestg2==bestg){
215
+ if(waste2<bds) take=true;
216
+ else if(waste2==bds){
217
+ if(bl2<bl) take=true;
218
+ else if(bl2==bl){
219
+ if(bdr2<bdr) take=true;
220
+ else if(bdr2==bdr){
221
+ if(by02<by0) take=true;
222
+ else if(by02==by0){
223
+ if(bx02<bx0) take=true;
224
+ else if(bx02==bx0 && randtie && rng.coin()) take=true;
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
231
+ }
232
+ if(bti==-1){t++;stepCnt++;if(big&&stepCnt==5){auto now=chrono::steady_clock::now(); auto elapsed=chrono::duration<double,milli>(now-tStart).count(); auto batch=chrono::duration<double,milli>(now-batchStart).count(); double remT=max(0.0,TLms-elapsed); int remSteps=max(1,nm-t); double budget=remT*5.0/remSteps; if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1); batchStart=now; stepCnt=0;} continue;}
233
+ auto &tsh=ps[bestid].t[bti];
234
+ for(int j=0;j<tsh.w;j++){
235
+ int nh=h[bx+j];
236
+ if(tsh.hi[j]!=INT_MIN){
237
+ int cand=by+tsh.hi[j];
238
+ if(nh<cand) nh=cand;
239
+ }
240
+ h[bx+j]=nh;
241
+ }
242
+ if(g<bl) g=bl;
243
+ pl.push_back({bestid,bti,bx,by});
244
+ if(bestpos!=t) swap(o[t],o[bestpos]);
245
+ t++;
246
+ stepCnt++;
247
+ if(big&&stepCnt==5){
248
+ auto now=chrono::steady_clock::now();
249
+ auto elapsed=chrono::duration<double,milli>(now-tStart).count();
250
+ auto batch=chrono::duration<double,milli>(now-batchStart).count();
251
+ double remT=max(0.0,TLms-elapsed);
252
+ int remSteps=max(1,nm-t);
253
+ double budget=remT*5.0/remSteps;
254
+ if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
255
+ batchStart=now;
256
+ stepCnt=0;
257
+ }
258
+ }
259
+ int H=(int)g+1;
260
+ int maxX=-1;
261
+ for(auto &pp:pl){
262
+ auto &t=ps[pp.idx].t[pp.ti];
263
+ for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}
264
+ }
265
+ int Wused=0;
266
+ if(maxX>=0){
267
+ vector<char> used(maxX+1,false);
268
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}}
269
+ for(int x=0;x<=maxX;x++) if(used[x]) Wused++;
270
+ }
271
+ int Wfinal=max(0,Wused);
272
+ long long A=1LL*H*max(1,Wfinal);
273
+ return R{A,max(1,Wfinal),H,move(pl)};
274
+ };
275
+ // Gap-filling pack for small inputs - tries positions below skyline using bitmap
276
+ auto pack_gap=[&](int W,const vector<int>& o0,RNG &rng,bool randtie) -> R {
277
+ int maxHg=(int)(S/max(1,W)+W+50);
278
+ vector<vector<bool>> grid(W, vector<bool>(maxHg, false));
279
+ vector<int> h(W,-1);
280
+ long long g=-1;
281
+ vector<Pl> pl; pl.reserve(o0.size());
282
+ vector<int> o=o0;
283
+ int t2=0,nm=(int)o.size();
284
+ int maxBound=max(1,n/4);
285
+ int dynLIM=maxBound;
286
+ bool gapEnabled=true;
287
+ while(t2<nm){
288
+ int earlyBoost=(t2<nm/10)?min(3,max(1,maxBound/dynLIM)):1;
289
+ int limCnt=max(1,dynLIM*earlyBoost);
290
+ int lim=min(nm,t2+limCnt);
291
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t2; int bestid=-1;
292
+ for(int pos=t2;pos<lim;pos++){
293
+ int id=o[pos];
294
+ auto &p=ps[id];
295
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
296
+ for(int ti=0;ti<(int)p.t.size();ti++){
297
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
298
+ for(int x0=0;x0<Rpos;x0++){
299
+ // Skyline placement
300
+ int y0=0;
301
+ for(int j=0;j<tsh.w;j++){
302
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
303
+ }
304
+ // Also try gap positions (scan up to 10 rows below skyline)
305
+ int gapY=-1;
306
+ if(gapEnabled && y0>0){
307
+ int sd=min(y0,3); // Only check 3 rows below skyline
308
+ for(int gy=max(0,y0-sd);gy<y0;gy++){
309
+ bool ok=true;
310
+ for(auto &q:tsh.c){
311
+ int gx=x0+q.first,gcy=gy+q.second;
312
+ if(gcy<0||gcy>=maxHg||grid[gx][gcy]){ok=false;break;}
313
+ }
314
+ if(ok){gapY=gy;break;}
315
+ }
316
+ }
317
+ // Evaluate both positions
318
+ for(int pass=0;pass<(gapY>=0?2:1);pass++){
319
+ int yy=(pass==0)?y0:gapY;
320
+ int nhbuf[32];
321
+ int l=-1; long long dsum=0;
322
+ for(int j=0;j<tsh.w;j++){
323
+ int nh=h[x0+j];
324
+ if(tsh.hi[j]!=INT_MIN){int cand=yy+tsh.hi[j]; if(nh<cand) nh=cand;}
325
+ nhbuf[j]=nh; if(nh>l) l=nh;
326
+ }
327
+ for(int j=0;j<tsh.w;j++){int inc=nhbuf[j]-h[x0+j]; if(inc>0) dsum+=inc;}
328
+ long long dr=0;
329
+ if(x0>0){dr+=llabs((long long)nhbuf[0]-h[x0-1])-llabs((long long)h[x0]-h[x0-1]);}
330
+ for(int j=0;j<tsh.w-1;j++){dr+=llabs((long long)nhbuf[j+1]-nhbuf[j])-llabs((long long)h[x0+j+1]-h[x0+j]);}
331
+ if(x0+tsh.w<W){dr+=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1])-llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);}
332
+ long long gg=g; if(gg<l) gg=l;
333
+ bool take=false;
334
+ if(gg<bestg2) take=true;
335
+ else if(gg==bestg2){
336
+ if(dsum<bds2) take=true;
337
+ else if(dsum==bds2){if(l<bl2) take=true;
338
+ else if(l==bl2){if(dr<bdr2) take=true;
339
+ else if(dr==bdr2){if(yy<by02) take=true;
340
+ else if(yy==by02){if(x0<bx02) take=true;
341
+ else if(x0==bx02&&randtie&&rng.coin()) take=true;}}}}
342
+ }
343
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=yy;bl2=l;bds2=dsum;bdr2=dr;by02=yy;bx02=x0;}
344
+ }
345
+ }
346
+ }
347
+ if(bti2==-1) continue;
348
+ long long waste2=bds2-p.k;
349
+ bool take=false;
350
+ if(bestg2<bestg) take=true;
351
+ else if(bestg2==bestg){if(waste2<bds) take=true;
352
+ else if(waste2==bds){if(bl2<bl) take=true;
353
+ else if(bl2==bl){if(bdr2<bdr) take=true;
354
+ else if(bdr2==bdr){if(by02<by0) take=true;
355
+ else if(by02==by0){if(bx02<bx0) take=true;
356
+ else if(bx02==bx0&&randtie&&rng.coin()) take=true;}}}}}
357
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
358
+ }
359
+ if(bti==-1){t2++;continue;}
360
+ auto &tsh=ps[bestid].t[bti];
361
+ for(int j=0;j<tsh.w;j++){
362
+ int nh=h[bx+j];
363
+ if(tsh.hi[j]!=INT_MIN){int cand=by+tsh.hi[j]; if(nh<cand) nh=cand;}
364
+ h[bx+j]=nh;
365
+ }
366
+ for(auto &q:tsh.c){int gx=bx+q.first,gy=by+q.second; if(gx>=0&&gx<W&&gy>=0&&gy<maxHg) grid[gx][gy]=true;}
367
+ if(g<bl) g=bl;
368
+ pl.push_back({bestid,bti,bx,by});
369
+ if(bestpos!=t2) swap(o[t2],o[bestpos]);
370
+ t2++;
371
+ }
372
+ if((int)pl.size() < nm){
373
+ // Not all pieces placed - return failure
374
+ return R{LLONG_MAX, W, 0, {}};
375
+ }
376
+ int H=(int)g+1;
377
+ int maxX=-1;
378
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}}
379
+ int Wused=0;
380
+ if(maxX>=0){vector<char> used(maxX+1,false); for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}} for(int x=0;x<=maxX;x++) if(used[x]) Wused++;}
381
+ int Wfinal=max(0,Wused);
382
+ long long A=1LL*H*max(1,Wfinal);
383
+ return R{A,max(1,Wfinal),H,move(pl)};
384
+ };
385
+ int minW=0; for(auto &p:ps) minW=max(minW,p.minW);
386
+
387
+ // Improved width estimation
388
+ double factor;
389
+ if (S < 1000) factor = 0.4;
390
+ else if (S < 3000) factor = 0.5;
391
+ else if (S < 10000) factor = 0.27;
392
+ else if (S < 30000) factor = 0.08;
393
+ else factor = 0.01;
394
+
395
+ int base = max(minW, (int)floor(sqrt((double)S * factor)));
396
+ vector<int> Ws;
397
+ {
398
+ unordered_set<int> used; used.reserve(512);
399
+ auto addW=[&](int w){if(w<minW) w=minW; if(used.insert(w).second) Ws.push_back(w);};
400
+ addW(base);
401
+ int span=min(96,max(20,base/2));
402
+ for(int d=1;d<=span;d++){addW(base-d); addW(base+d);}
403
+ addW(minW);
404
+ addW((int)max<long long>(minW,(S+base-1)/base));
405
+ for(int m=2;m<=6;m++){addW(base*m/3); addW((int)max<long long>(minW,S/((base*m/3)?(base*m/3):1)));}
406
+ // Add sqrt(S) based widths for more square-like rectangles
407
+ int sqrtS = max(minW, (int)floor(sqrt((double)S)));
408
+ addW(sqrtS);
409
+ addW(sqrtS+1);
410
+ addW(sqrtS-1);
411
+ addW(sqrtS*2/3);
412
+ addW(sqrtS/2);
413
+ sort(Ws.begin(),Ws.end(),[&](int a,int b){int da=abs(a-base),db=abs(b-base); if(da!=db) return da<db; return a<b;});
414
+ }
415
+ long long bestA=LLONG_MAX; int bestW=0,bestH=0; R bestR; bool hasBestmine=false;
416
+ auto t0=chrono::steady_clock::now();
417
+ const double TL=1980.0;
418
+ double avg=250.0; int cnt=0;
419
+
420
+ // Prepare orderings - fewer for gap packer (slower per call)
421
+ bool useGapPacker = (S < 2500);
422
+ vector<vector<int>> base_orders;
423
+ base_orders.push_back(ord_asc_mindim());
424
+ if(!useGapPacker){
425
+ base_orders.push_back(ord_desc_area());
426
+ base_orders.push_back(ord_desc_maxdim());
427
+ base_orders.push_back(ord_desc_bbox());
428
+ base_orders.push_back(ord_flexibility());
429
+ }
430
+ auto doPack = [&](int W, const vector<int>& order, RNG& rng, bool randtie) -> R {
431
+ if(useGapPacker) return pack_gap(W, order, rng, randtie);
432
+ return pack(W, order, rng, randtie);
433
+ };
434
+
435
+ // Track best ordering index per width for perturbation
436
+ int bestOrderIdx = 0;
437
+
438
+ for(int wi=0;wi<(int)Ws.size();wi++){
439
+ auto now=chrono::steady_clock::now();
440
+ double used_time=chrono::duration<double,milli>(now-t0).count();
441
+ if(used_time+avg*1.3>TL) break;
442
+ int W=Ws[wi];
443
+
444
+ // Try each base ordering
445
+ for(int oi=0;oi<(int)base_orders.size();oi++){
446
+ now=chrono::steady_clock::now();
447
+ double used2=chrono::duration<double,milli>(now-t0).count();
448
+ if(used2+avg*1.15>TL) break;
449
+ bool randtie=(oi>=1);
450
+ auto t1=chrono::steady_clock::now();
451
+ R r=doPack(W,base_orders[oi],rng,randtie);
452
+ auto t2=chrono::steady_clock::now();
453
+ double dt=chrono::duration<double,milli>(t2-t1).count();
454
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
455
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
456
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
457
+ bestOrderIdx=oi;
458
+ }
459
+ }
460
+
461
+ // Perturbation of best ordering + random orderings
462
+ int nswaps = max(1, n/20);
463
+ int maxRandom = useGapPacker ? 1 : 4;
464
+ for(int ri=0;ri<maxRandom;ri++){
465
+ now=chrono::steady_clock::now();
466
+ double used2=chrono::duration<double,milli>(now-t0).count();
467
+ if(used2+avg*1.15>TL) break;
468
+ auto t1=chrono::steady_clock::now();
469
+ vector<int> order;
470
+ if(ri < 2) order = ord_perturb(base_orders[bestOrderIdx], nswaps);
471
+ else order = ord_random();
472
+ R r=doPack(W,order,rng,true);
473
+ auto t2=chrono::steady_clock::now();
474
+ double dt=chrono::duration<double,milli>(t2-t1).count();
475
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
476
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
477
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
478
+ }
479
+ }
480
+ }
481
+ if(!hasBestmine){
482
+ int W=max(minW,(int)floor(sqrt((double)S)));
483
+ auto o=ord_asc_mindim();
484
+ R r=pack(W,o,rng,false);
485
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
486
+ }
487
+ int maxX=-1;
488
+ for(auto &p:bestR.pl){
489
+ auto &t=ps[p.idx].t[p.ti];
490
+ for(auto &q:t.c){int x=p.x+q.first; if(x>maxX) maxX=x;}
491
+ }
492
+ vector<int> mapx(maxX+1,-1);
493
+ if(maxX>=0){
494
+ vector<char> used(maxX+1,false);
495
+ for(auto &p:bestR.pl){
496
+ auto &t=ps[p.idx].t[p.ti];
497
+ for(auto &q:t.c){used[p.x+q.first]=true;}
498
+ }
499
+ int cur=0;
500
+ for(int x=0;x<=maxX;x++) if(used[x]) mapx[x]=cur++;
501
+ }
502
+ vector<array<int,4>> ans(n,{0,0,0,0});
503
+ for(auto &p:bestR.pl){
504
+ auto &t=ps[p.idx].t[p.ti];
505
+ int bx = (mapx.empty()?p.x:mapx[p.x]);
506
+ int Xi = bx - t.minx;
507
+ int Yi = p.y - t.miny;
508
+ int Ri = (4 - (t.r%4) + 4) % 4;
509
+ int Fi = t.f;
510
+ ans[p.idx]={Xi,Yi,Ri,Fi};
511
+ }
512
+ cout<<bestR.W<<" "<<bestR.H<<"\n";
513
+ for(int i=0;i<n;i++){
514
+ cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<"\n";
515
+ }
516
+ return 0;
517
+ }
docker_space/frontier_cs_0_polyomino_ev2/logs/gen_3.cpp ADDED
@@ -0,0 +1,395 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Gen 1: Multiple orderings + improved width search
3
+ Based on reference.cpp with:
4
+ - 4 ordering strategies (ascending min dim, descending area, descending max dim, random)
5
+ - Each width tries all orderings (time permitting)
6
+ - Better width candidate generation
7
+ */
8
+ #include <bits/stdc++.h>
9
+ using namespace std;
10
+ struct T{int w,h;vector<pair<int,int>> c;vector<int> lo,hi;int r,f,minx,miny;};
11
+ struct P{int id,k;vector<pair<int,int>> b;vector<T> t;int minW=1e9,minH=1e9,minA=1e9;};
12
+ struct Pl{int idx,ti,x,y;};
13
+ struct R{long long A;int W,H;vector<Pl> pl;};
14
+ struct RNG{unsigned long long s;RNG(unsigned long long x){s=x?x:1;}inline unsigned long long nxt(){s^=s<<7;s^=s>>9;return s;}inline int rint(int n){return (int)(nxt()%n);}inline bool coin(){return nxt()&1;}};
15
+ static inline pair<int,int> rotp(pair<int,int> p,int r){if(r==0)return p; if(r==1)return make_pair(-p.second,p.first); if(r==2)return make_pair(-p.first,-p.second); return make_pair(p.second,-p.first);}
16
+ int main(){
17
+ ios::sync_with_stdio(false);
18
+ cin.tie(nullptr);
19
+ int n; if(!(cin>>n)) return 0;
20
+ vector<P> ps(n); long long S=0;
21
+ for(int i=0;i<n;i++){
22
+ int k;cin>>k; ps[i].id=i+1; ps[i].k=k; ps[i].b.resize(k);
23
+ for(int j=0;j<k;j++){int x,y;cin>>x>>y; ps[i].b[j]={x,y};}
24
+ S+=k;
25
+ }
26
+ for(int i=0;i<n;i++){
27
+ auto &p=ps[i]; unordered_set<string> seen; seen.reserve(32);
28
+ for(int rf=0;rf<2;rf++){
29
+ vector<pair<int,int>> src=p.b; if(rf){for(auto &q:src) q.first=-q.first;}
30
+ for(int r=0;r<4;r++){
31
+ vector<pair<int,int>> v=src; for(auto &q:v) q=rotp(q,r);
32
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
33
+ for(auto &q:v){minx=min(minx,q.first);miny=min(miny,q.second);maxx=max(maxx,q.first);maxy=max(maxy,q.second);}
34
+ vector<pair<int,int>> v2=v; for(auto &q:v2){q.first-=minx;q.second-=miny;}
35
+ sort(v2.begin(),v2.end());
36
+ string key; key.reserve(v2.size()*8);
37
+ for(auto &q:v2){key.append(to_string(q.first));key.push_back(',');key.append(to_string(q.second));key.push_back(';');}
38
+ if(seen.insert(key).second){
39
+ T t; t.w=maxx-minx+1; t.h=maxy-miny+1; t.c=v2; t.r=r; t.f=rf; t.minx=minx; t.miny=miny;
40
+ t.lo.assign(t.w,INT_MAX); t.hi.assign(t.w,INT_MIN);
41
+ for(auto &q:v2){int x=q.first,y=q.second; if(t.lo[x]>y) t.lo[x]=y; if(t.hi[x]<y) t.hi[x]=y;}
42
+ p.t.push_back(move(t));
43
+ }
44
+ }
45
+ }
46
+ for(auto &t:p.t){p.minW=min(p.minW,t.w); p.minH=min(p.minH,t.h); p.minA=min(p.minA,t.w*t.h);}
47
+ if(p.t.empty()){T t; t.w=1;t.h=1;t.c={{0,0}};t.lo={0};t.hi={0};t.r=0;t.f=0;t.minx=0;t.miny=0;p.t.push_back(t);p.minW=1;p.minH=1;p.minA=1;}
48
+ }
49
+ vector<int> idx(n); iota(idx.begin(),idx.end(),0);
50
+ unsigned long long seed=((unsigned long long)chrono::high_resolution_clock::now().time_since_epoch().count()) ^ (S<<1) ^ (unsigned long long)(n*1469598103934665603ULL);
51
+ RNG rng(seed);
52
+
53
+ // Multiple ordering strategies
54
+ auto ord_asc_mindim = [&]() {
55
+ vector<int> res = idx;
56
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
57
+ int da = min(ps[a].minW, ps[a].minH);
58
+ int db = min(ps[b].minW, ps[b].minH);
59
+ if (da != db) return da < db;
60
+ if (ps[a].k != ps[b].k) return ps[a].k < ps[b].k;
61
+ return ps[a].id > ps[b].id;
62
+ });
63
+ return res;
64
+ };
65
+ auto ord_desc_area = [&]() {
66
+ vector<int> res = idx;
67
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
68
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
69
+ int da = min(ps[a].minW, ps[a].minH);
70
+ int db = min(ps[b].minW, ps[b].minH);
71
+ if (da != db) return da > db;
72
+ return ps[a].id < ps[b].id;
73
+ });
74
+ return res;
75
+ };
76
+ auto ord_desc_maxdim = [&]() {
77
+ vector<int> res = idx;
78
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
79
+ int da = max(ps[a].minW, ps[a].minH);
80
+ int db = max(ps[b].minW, ps[b].minH);
81
+ if (da != db) return da > db;
82
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
83
+ return ps[a].id < ps[b].id;
84
+ });
85
+ return res;
86
+ };
87
+ auto ord_desc_bbox = [&]() {
88
+ vector<int> res = idx;
89
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
90
+ if (ps[a].minA != ps[b].minA) return ps[a].minA > ps[b].minA;
91
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
92
+ return ps[a].id < ps[b].id;
93
+ });
94
+ return res;
95
+ };
96
+ auto ord_random = [&]() {
97
+ vector<int> res = idx;
98
+ for(int i=n-1;i>0;i--){
99
+ int j=rng.rint(i+1);
100
+ swap(res[i],res[j]);
101
+ }
102
+ return res;
103
+ };
104
+ // Perturb a given ordering by making random swaps
105
+ auto ord_perturb = [&](const vector<int>& base_ord, int nswaps) {
106
+ vector<int> res = base_ord;
107
+ for(int i=0;i<nswaps;i++){
108
+ int a=rng.rint(n), b=rng.rint(n);
109
+ swap(res[a],res[b]);
110
+ }
111
+ return res;
112
+ };
113
+ // Sort by flexibility (fewer variants first = harder to place)
114
+ auto ord_flexibility = [&]() {
115
+ vector<int> res = idx;
116
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
117
+ int va=(int)ps[a].t.size(), vb=(int)ps[b].t.size();
118
+ if(va!=vb) return va<vb;
119
+ if(ps[a].k!=ps[b].k) return ps[a].k>ps[b].k;
120
+ return ps[a].id<ps[b].id;
121
+ });
122
+ return res;
123
+ };
124
+
125
+ auto pack=[&](int W,const vector<int>& o0,RNG &rng,bool randtie){
126
+ vector<int> h(W,-1);
127
+ long long g=-1;
128
+ vector<Pl> pl; pl.reserve(o0.size());
129
+ vector<int> o=o0;
130
+ int t=0,nm=(int)o.size();
131
+ bool big=S>7000;
132
+ int maxBound=max(1,n/4);
133
+ int expLIM=min(maxBound,(int)(350000/max(1LL,S-3500)));
134
+ int dynLIM=big?expLIM:maxBound;
135
+ auto tStart=chrono::steady_clock::now();
136
+ auto batchStart=tStart;
137
+ long long TLms=big?1900:LLONG_MAX/4;
138
+ int stepCnt=0;
139
+ while(t<nm){
140
+ int limCnt=max(1,dynLIM);
141
+ int lim=min(nm,t+limCnt);
142
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t; int bestid=-1;
143
+ for(int pos=t;pos<lim;pos++){
144
+ int id=o[pos];
145
+ auto &p=ps[id];
146
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
147
+ for(int ti=0;ti<(int)p.t.size();ti++){
148
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
149
+ for(int x0=0;x0<Rpos;x0++){
150
+ int y0=0;
151
+ for(int j=0;j<tsh.w;j++){
152
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
153
+ }
154
+ int nhbuf[32];
155
+ int l=-1; long long dsum=0;
156
+ for(int j=0;j<tsh.w;j++){
157
+ int nh=h[x0+j];
158
+ if(tsh.hi[j]!=INT_MIN){
159
+ int cand=y0+tsh.hi[j];
160
+ if(nh<cand) nh=cand;
161
+ }
162
+ nhbuf[j]=nh;
163
+ if(nh>l) l=nh;
164
+ }
165
+ for(int j=0;j<tsh.w;j++){
166
+ int inc=nhbuf[j]-h[x0+j];
167
+ if(inc>0) dsum+=inc;
168
+ }
169
+ long long dr=0;
170
+ if(x0>0){
171
+ long long old=llabs((long long)h[x0]-h[x0-1]);
172
+ long long nw=llabs((long long)nhbuf[0]-h[x0-1]);
173
+ dr+=nw-old;
174
+ }
175
+ for(int j=0;j<tsh.w-1;j++){
176
+ long long old=llabs((long long)h[x0+j+1]-h[x0+j]);
177
+ long long nw=llabs((long long)nhbuf[j+1]-nhbuf[j]);
178
+ dr+=nw-old;
179
+ }
180
+ if(x0+tsh.w<W){
181
+ long long old=llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);
182
+ long long nw=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1]);
183
+ dr+=nw-old;
184
+ }
185
+ long long gg=g; if(gg<l) gg=l;
186
+ bool take=false;
187
+ if(gg<bestg2) take=true;
188
+ else if(gg==bestg2){
189
+ if(dsum<bds2) take=true;
190
+ else if(dsum==bds2){
191
+ if(l<bl2) take=true;
192
+ else if(l==bl2){
193
+ if(dr<bdr2) take=true;
194
+ else if(dr==bdr2){
195
+ if(y0<by02) take=true;
196
+ else if(y0==by02){
197
+ if(x0<bx02) take=true;
198
+ else if(x0==bx02 && randtie && rng.coin()) take=true;
199
+ }
200
+ }
201
+ }
202
+ }
203
+ }
204
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=y0;bl2=l;bds2=dsum;bdr2=dr;by02=y0;bx02=x0;}
205
+ }
206
+ }
207
+ if(bti2==-1) continue;
208
+ bool take=false;
209
+ if(bestg2<bestg) take=true;
210
+ else if(bestg2==bestg){
211
+ if(bds2<bds) take=true;
212
+ else if(bds2==bds){
213
+ if(bl2<bl) take=true;
214
+ else if(bl2==bl){
215
+ if(bdr2<bdr) take=true;
216
+ else if(bdr2==bdr){
217
+ if(by02<by0) take=true;
218
+ else if(by02==by0){
219
+ if(bx02<bx0) take=true;
220
+ else if(bx02==bx0 && randtie && rng.coin()) take=true;
221
+ }
222
+ }
223
+ }
224
+ }
225
+ }
226
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=bds2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
227
+ }
228
+ if(bti==-1){t++;stepCnt++;if(big&&stepCnt==5){auto now=chrono::steady_clock::now(); auto elapsed=chrono::duration<double,milli>(now-tStart).count(); auto batch=chrono::duration<double,milli>(now-batchStart).count(); double remT=max(0.0,TLms-elapsed); int remSteps=max(1,nm-t); double budget=remT*5.0/remSteps; if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1); batchStart=now; stepCnt=0;} continue;}
229
+ auto &tsh=ps[bestid].t[bti];
230
+ for(int j=0;j<tsh.w;j++){
231
+ int nh=h[bx+j];
232
+ if(tsh.hi[j]!=INT_MIN){
233
+ int cand=by+tsh.hi[j];
234
+ if(nh<cand) nh=cand;
235
+ }
236
+ h[bx+j]=nh;
237
+ }
238
+ if(g<bl) g=bl;
239
+ pl.push_back({bestid,bti,bx,by});
240
+ if(bestpos!=t) swap(o[t],o[bestpos]);
241
+ t++;
242
+ stepCnt++;
243
+ if(big&&stepCnt==5){
244
+ auto now=chrono::steady_clock::now();
245
+ auto elapsed=chrono::duration<double,milli>(now-tStart).count();
246
+ auto batch=chrono::duration<double,milli>(now-batchStart).count();
247
+ double remT=max(0.0,TLms-elapsed);
248
+ int remSteps=max(1,nm-t);
249
+ double budget=remT*5.0/remSteps;
250
+ if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
251
+ batchStart=now;
252
+ stepCnt=0;
253
+ }
254
+ }
255
+ int H=(int)g+1;
256
+ int maxX=-1;
257
+ for(auto &pp:pl){
258
+ auto &t=ps[pp.idx].t[pp.ti];
259
+ for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}
260
+ }
261
+ int Wused=0;
262
+ if(maxX>=0){
263
+ vector<char> used(maxX+1,false);
264
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}}
265
+ for(int x=0;x<=maxX;x++) if(used[x]) Wused++;
266
+ }
267
+ int Wfinal=max(0,Wused);
268
+ long long A=1LL*H*max(1,Wfinal);
269
+ return R{A,max(1,Wfinal),H,move(pl)};
270
+ };
271
+ int minW=0; for(auto &p:ps) minW=max(minW,p.minW);
272
+
273
+ // Improved width estimation
274
+ double factor;
275
+ if (S < 1000) factor = 0.4;
276
+ else if (S < 3000) factor = 0.5;
277
+ else if (S < 10000) factor = 0.27;
278
+ else if (S < 30000) factor = 0.08;
279
+ else factor = 0.01;
280
+
281
+ int base = max(minW, (int)floor(sqrt((double)S * factor)));
282
+ vector<int> Ws;
283
+ {
284
+ unordered_set<int> used; used.reserve(512);
285
+ auto addW=[&](int w){if(w<minW) w=minW; if(used.insert(w).second) Ws.push_back(w);};
286
+ addW(base);
287
+ int span=min(96,max(20,base/2));
288
+ for(int d=1;d<=span;d++){addW(base-d); addW(base+d);}
289
+ addW(minW);
290
+ addW((int)max<long long>(minW,(S+base-1)/base));
291
+ for(int m=2;m<=6;m++){addW(base*m/3); addW((int)max<long long>(minW,S/((base*m/3)?(base*m/3):1)));}
292
+ // Add sqrt(S) based widths for more square-like rectangles
293
+ int sqrtS = max(minW, (int)floor(sqrt((double)S)));
294
+ addW(sqrtS);
295
+ addW(sqrtS+1);
296
+ addW(sqrtS-1);
297
+ addW(sqrtS*2/3);
298
+ addW(sqrtS/2);
299
+ sort(Ws.begin(),Ws.end(),[&](int a,int b){int da=abs(a-base),db=abs(b-base); if(da!=db) return da<db; return a<b;});
300
+ }
301
+ long long bestA=LLONG_MAX; int bestW=0,bestH=0; R bestR; bool hasBestmine=false;
302
+ auto t0=chrono::steady_clock::now();
303
+ const double TL=1980.0;
304
+ double avg=250.0; int cnt=0;
305
+
306
+ // Prepare multiple orderings
307
+ vector<vector<int>> base_orders;
308
+ base_orders.push_back(ord_asc_mindim());
309
+ base_orders.push_back(ord_desc_area());
310
+ base_orders.push_back(ord_desc_maxdim());
311
+ base_orders.push_back(ord_desc_bbox());
312
+ base_orders.push_back(ord_flexibility());
313
+
314
+ // Track best ordering index per width for perturbation
315
+ int bestOrderIdx = 0;
316
+
317
+ for(int wi=0;wi<(int)Ws.size();wi++){
318
+ auto now=chrono::steady_clock::now();
319
+ double used_time=chrono::duration<double,milli>(now-t0).count();
320
+ if(used_time+avg*1.3>TL) break;
321
+ int W=Ws[wi];
322
+
323
+ // Try each base ordering
324
+ for(int oi=0;oi<(int)base_orders.size();oi++){
325
+ now=chrono::steady_clock::now();
326
+ double used2=chrono::duration<double,milli>(now-t0).count();
327
+ if(used2+avg*1.15>TL) break;
328
+ bool randtie=(oi>=1);
329
+ auto t1=chrono::steady_clock::now();
330
+ R r=pack(W,base_orders[oi],rng,randtie);
331
+ auto t2=chrono::steady_clock::now();
332
+ double dt=chrono::duration<double,milli>(t2-t1).count();
333
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
334
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
335
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
336
+ bestOrderIdx=oi;
337
+ }
338
+ }
339
+
340
+ // Perturbation of best ordering + random orderings
341
+ int nswaps = max(1, n/20);
342
+ for(int ri=0;ri<4;ri++){
343
+ now=chrono::steady_clock::now();
344
+ double used2=chrono::duration<double,milli>(now-t0).count();
345
+ if(used2+avg*1.15>TL) break;
346
+ auto t1=chrono::steady_clock::now();
347
+ vector<int> order;
348
+ if(ri < 2) order = ord_perturb(base_orders[bestOrderIdx], nswaps);
349
+ else order = ord_random();
350
+ R r=pack(W,order,rng,true);
351
+ auto t2=chrono::steady_clock::now();
352
+ double dt=chrono::duration<double,milli>(t2-t1).count();
353
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
354
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
355
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
356
+ }
357
+ }
358
+ }
359
+ if(!hasBestmine){
360
+ int W=max(minW,(int)floor(sqrt((double)S)));
361
+ auto o=ord_asc_mindim();
362
+ R r=pack(W,o,rng,false);
363
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
364
+ }
365
+ int maxX=-1;
366
+ for(auto &p:bestR.pl){
367
+ auto &t=ps[p.idx].t[p.ti];
368
+ for(auto &q:t.c){int x=p.x+q.first; if(x>maxX) maxX=x;}
369
+ }
370
+ vector<int> mapx(maxX+1,-1);
371
+ if(maxX>=0){
372
+ vector<char> used(maxX+1,false);
373
+ for(auto &p:bestR.pl){
374
+ auto &t=ps[p.idx].t[p.ti];
375
+ for(auto &q:t.c){used[p.x+q.first]=true;}
376
+ }
377
+ int cur=0;
378
+ for(int x=0;x<=maxX;x++) if(used[x]) mapx[x]=cur++;
379
+ }
380
+ vector<array<int,4>> ans(n,{0,0,0,0});
381
+ for(auto &p:bestR.pl){
382
+ auto &t=ps[p.idx].t[p.ti];
383
+ int bx = (mapx.empty()?p.x:mapx[p.x]);
384
+ int Xi = bx - t.minx;
385
+ int Yi = p.y - t.miny;
386
+ int Ri = (4 - (t.r%4) + 4) % 4;
387
+ int Fi = t.f;
388
+ ans[p.idx]={Xi,Yi,Ri,Fi};
389
+ }
390
+ cout<<bestR.W<<" "<<bestR.H<<"\n";
391
+ for(int i=0;i<n;i++){
392
+ cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<"\n";
393
+ }
394
+ return 0;
395
+ }
docker_space/frontier_cs_0_polyomino_ev2/logs/gen_30.cpp ADDED
@@ -0,0 +1,517 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Gen 1: Multiple orderings + improved width search
3
+ Based on reference.cpp with:
4
+ - 4 ordering strategies (ascending min dim, descending area, descending max dim, random)
5
+ - Each width tries all orderings (time permitting)
6
+ - Better width candidate generation
7
+ */
8
+ #include <bits/stdc++.h>
9
+ using namespace std;
10
+ struct T{int w,h;vector<pair<int,int>> c;vector<int> lo,hi;int r,f,minx,miny;};
11
+ struct P{int id,k;vector<pair<int,int>> b;vector<T> t;int minW=1e9,minH=1e9,minA=1e9;};
12
+ struct Pl{int idx,ti,x,y;};
13
+ struct R{long long A;int W,H;vector<Pl> pl;};
14
+ struct RNG{unsigned long long s;RNG(unsigned long long x){s=x?x:1;}inline unsigned long long nxt(){s^=s<<7;s^=s>>9;return s;}inline int rint(int n){return (int)(nxt()%n);}inline bool coin(){return nxt()&1;}};
15
+ static inline pair<int,int> rotp(pair<int,int> p,int r){if(r==0)return p; if(r==1)return make_pair(-p.second,p.first); if(r==2)return make_pair(-p.first,-p.second); return make_pair(p.second,-p.first);}
16
+ int main(){
17
+ ios::sync_with_stdio(false);
18
+ cin.tie(nullptr);
19
+ int n; if(!(cin>>n)) return 0;
20
+ vector<P> ps(n); long long S=0;
21
+ for(int i=0;i<n;i++){
22
+ int k;cin>>k; ps[i].id=i+1; ps[i].k=k; ps[i].b.resize(k);
23
+ for(int j=0;j<k;j++){int x,y;cin>>x>>y; ps[i].b[j]={x,y};}
24
+ S+=k;
25
+ }
26
+ for(int i=0;i<n;i++){
27
+ auto &p=ps[i]; unordered_set<string> seen; seen.reserve(32);
28
+ for(int rf=0;rf<2;rf++){
29
+ vector<pair<int,int>> src=p.b; if(rf){for(auto &q:src) q.first=-q.first;}
30
+ for(int r=0;r<4;r++){
31
+ vector<pair<int,int>> v=src; for(auto &q:v) q=rotp(q,r);
32
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
33
+ for(auto &q:v){minx=min(minx,q.first);miny=min(miny,q.second);maxx=max(maxx,q.first);maxy=max(maxy,q.second);}
34
+ vector<pair<int,int>> v2=v; for(auto &q:v2){q.first-=minx;q.second-=miny;}
35
+ sort(v2.begin(),v2.end());
36
+ string key; key.reserve(v2.size()*8);
37
+ for(auto &q:v2){key.append(to_string(q.first));key.push_back(',');key.append(to_string(q.second));key.push_back(';');}
38
+ if(seen.insert(key).second){
39
+ T t; t.w=maxx-minx+1; t.h=maxy-miny+1; t.c=v2; t.r=r; t.f=rf; t.minx=minx; t.miny=miny;
40
+ t.lo.assign(t.w,INT_MAX); t.hi.assign(t.w,INT_MIN);
41
+ for(auto &q:v2){int x=q.first,y=q.second; if(t.lo[x]>y) t.lo[x]=y; if(t.hi[x]<y) t.hi[x]=y;}
42
+ p.t.push_back(move(t));
43
+ }
44
+ }
45
+ }
46
+ for(auto &t:p.t){p.minW=min(p.minW,t.w); p.minH=min(p.minH,t.h); p.minA=min(p.minA,t.w*t.h);}
47
+ if(p.t.empty()){T t; t.w=1;t.h=1;t.c={{0,0}};t.lo={0};t.hi={0};t.r=0;t.f=0;t.minx=0;t.miny=0;p.t.push_back(t);p.minW=1;p.minH=1;p.minA=1;}
48
+ }
49
+ vector<int> idx(n); iota(idx.begin(),idx.end(),0);
50
+ unsigned long long seed=((unsigned long long)chrono::high_resolution_clock::now().time_since_epoch().count()) ^ (S<<1) ^ (unsigned long long)(n*1469598103934665603ULL);
51
+ RNG rng(seed);
52
+
53
+ // Multiple ordering strategies
54
+ auto ord_asc_mindim = [&]() {
55
+ vector<int> res = idx;
56
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
57
+ int da = min(ps[a].minW, ps[a].minH);
58
+ int db = min(ps[b].minW, ps[b].minH);
59
+ if (da != db) return da < db;
60
+ if (ps[a].k != ps[b].k) return ps[a].k < ps[b].k;
61
+ return ps[a].id > ps[b].id;
62
+ });
63
+ return res;
64
+ };
65
+ auto ord_desc_area = [&]() {
66
+ vector<int> res = idx;
67
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
68
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
69
+ int da = min(ps[a].minW, ps[a].minH);
70
+ int db = min(ps[b].minW, ps[b].minH);
71
+ if (da != db) return da > db;
72
+ return ps[a].id < ps[b].id;
73
+ });
74
+ return res;
75
+ };
76
+ auto ord_desc_maxdim = [&]() {
77
+ vector<int> res = idx;
78
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
79
+ int da = max(ps[a].minW, ps[a].minH);
80
+ int db = max(ps[b].minW, ps[b].minH);
81
+ if (da != db) return da > db;
82
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
83
+ return ps[a].id < ps[b].id;
84
+ });
85
+ return res;
86
+ };
87
+ auto ord_desc_bbox = [&]() {
88
+ vector<int> res = idx;
89
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
90
+ if (ps[a].minA != ps[b].minA) return ps[a].minA > ps[b].minA;
91
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
92
+ return ps[a].id < ps[b].id;
93
+ });
94
+ return res;
95
+ };
96
+ auto ord_random = [&]() {
97
+ vector<int> res = idx;
98
+ for(int i=n-1;i>0;i--){
99
+ int j=rng.rint(i+1);
100
+ swap(res[i],res[j]);
101
+ }
102
+ return res;
103
+ };
104
+ // Perturb a given ordering by making random swaps
105
+ auto ord_perturb = [&](const vector<int>& base_ord, int nswaps) {
106
+ vector<int> res = base_ord;
107
+ for(int i=0;i<nswaps;i++){
108
+ int a=rng.rint(n), b=rng.rint(n);
109
+ swap(res[a],res[b]);
110
+ }
111
+ return res;
112
+ };
113
+ // Sort by flexibility (fewer variants first = harder to place)
114
+ auto ord_flexibility = [&]() {
115
+ vector<int> res = idx;
116
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
117
+ int va=(int)ps[a].t.size(), vb=(int)ps[b].t.size();
118
+ if(va!=vb) return va<vb;
119
+ if(ps[a].k!=ps[b].k) return ps[a].k>ps[b].k;
120
+ return ps[a].id<ps[b].id;
121
+ });
122
+ return res;
123
+ };
124
+
125
+ auto pack=[&](int W,const vector<int>& o0,RNG &rng,bool randtie){
126
+ vector<int> h(W,-1);
127
+ long long g=-1;
128
+ vector<Pl> pl; pl.reserve(o0.size());
129
+ vector<int> o=o0;
130
+ int t=0,nm=(int)o.size();
131
+ bool big=S>7000;
132
+ int maxBound=max(1,n/4);
133
+ int expLIM=min(maxBound,(int)(350000/max(1LL,S-3500)));
134
+ int dynLIM=big?expLIM:maxBound;
135
+ auto tStart=chrono::steady_clock::now();
136
+ auto batchStart=tStart;
137
+ long long TLms=big?1900:LLONG_MAX/4;
138
+ int stepCnt=0;
139
+ while(t<nm){
140
+ // Increase lookahead for early pieces (they have most impact)
141
+ int earlyBoost = (t < nm/10) ? min(3, max(1, maxBound/dynLIM)) : 1;
142
+ int limCnt=max(1,dynLIM * earlyBoost);
143
+ int lim=min(nm,t+limCnt);
144
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t; int bestid=-1;
145
+ for(int pos=t;pos<lim;pos++){
146
+ int id=o[pos];
147
+ auto &p=ps[id];
148
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
149
+ for(int ti=0;ti<(int)p.t.size();ti++){
150
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
151
+ for(int x0=0;x0<Rpos;x0++){
152
+ int y0=0;
153
+ for(int j=0;j<tsh.w;j++){
154
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
155
+ }
156
+ int nhbuf[32];
157
+ int l=-1; long long dsum=0;
158
+ for(int j=0;j<tsh.w;j++){
159
+ int nh=h[x0+j];
160
+ if(tsh.hi[j]!=INT_MIN){
161
+ int cand=y0+tsh.hi[j];
162
+ if(nh<cand) nh=cand;
163
+ }
164
+ nhbuf[j]=nh;
165
+ if(nh>l) l=nh;
166
+ }
167
+ for(int j=0;j<tsh.w;j++){
168
+ int inc=nhbuf[j]-h[x0+j];
169
+ if(inc>0) dsum+=inc;
170
+ }
171
+ long long dr=0;
172
+ if(x0>0){
173
+ long long old=llabs((long long)h[x0]-h[x0-1]);
174
+ long long nw=llabs((long long)nhbuf[0]-h[x0-1]);
175
+ dr+=nw-old;
176
+ }
177
+ for(int j=0;j<tsh.w-1;j++){
178
+ long long old=llabs((long long)h[x0+j+1]-h[x0+j]);
179
+ long long nw=llabs((long long)nhbuf[j+1]-nhbuf[j]);
180
+ dr+=nw-old;
181
+ }
182
+ if(x0+tsh.w<W){
183
+ long long old=llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);
184
+ long long nw=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1]);
185
+ dr+=nw-old;
186
+ }
187
+ long long gg=g; if(gg<l) gg=l;
188
+ bool take=false;
189
+ if(gg<bestg2) take=true;
190
+ else if(gg==bestg2){
191
+ if(dsum<bds2) take=true;
192
+ else if(dsum==bds2){
193
+ if(l<bl2) take=true;
194
+ else if(l==bl2){
195
+ if(dr<bdr2) take=true;
196
+ else if(dr==bdr2){
197
+ if(y0<by02) take=true;
198
+ else if(y0==by02){
199
+ if(x0<bx02) take=true;
200
+ else if(x0==bx02 && randtie && rng.coin()) take=true;
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
206
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=y0;bl2=l;bds2=dsum;bdr2=dr;by02=y0;bx02=x0;}
207
+ }
208
+ }
209
+ if(bti2==-1) continue;
210
+ // Use waste = dsum - k for between-piece comparison (accounts for piece size)
211
+ long long waste2 = bds2 - p.k;
212
+ bool take=false;
213
+ if(bestg2<bestg) take=true;
214
+ else if(bestg2==bestg){
215
+ if(waste2<bds) take=true;
216
+ else if(waste2==bds){
217
+ if(bl2<bl) take=true;
218
+ else if(bl2==bl){
219
+ if(bdr2<bdr) take=true;
220
+ else if(bdr2==bdr){
221
+ if(by02<by0) take=true;
222
+ else if(by02==by0){
223
+ if(bx02<bx0) take=true;
224
+ else if(bx02==bx0 && randtie && rng.coin()) take=true;
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
231
+ }
232
+ if(bti==-1){t++;stepCnt++;if(big&&stepCnt==5){auto now=chrono::steady_clock::now(); auto elapsed=chrono::duration<double,milli>(now-tStart).count(); auto batch=chrono::duration<double,milli>(now-batchStart).count(); double remT=max(0.0,TLms-elapsed); int remSteps=max(1,nm-t); double budget=remT*5.0/remSteps; if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1); batchStart=now; stepCnt=0;} continue;}
233
+ auto &tsh=ps[bestid].t[bti];
234
+ for(int j=0;j<tsh.w;j++){
235
+ int nh=h[bx+j];
236
+ if(tsh.hi[j]!=INT_MIN){
237
+ int cand=by+tsh.hi[j];
238
+ if(nh<cand) nh=cand;
239
+ }
240
+ h[bx+j]=nh;
241
+ }
242
+ if(g<bl) g=bl;
243
+ pl.push_back({bestid,bti,bx,by});
244
+ if(bestpos!=t) swap(o[t],o[bestpos]);
245
+ t++;
246
+ stepCnt++;
247
+ if(big&&stepCnt==5){
248
+ auto now=chrono::steady_clock::now();
249
+ auto elapsed=chrono::duration<double,milli>(now-tStart).count();
250
+ auto batch=chrono::duration<double,milli>(now-batchStart).count();
251
+ double remT=max(0.0,TLms-elapsed);
252
+ int remSteps=max(1,nm-t);
253
+ double budget=remT*5.0/remSteps;
254
+ if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
255
+ batchStart=now;
256
+ stepCnt=0;
257
+ }
258
+ }
259
+ int H=(int)g+1;
260
+ int maxX=-1;
261
+ for(auto &pp:pl){
262
+ auto &t=ps[pp.idx].t[pp.ti];
263
+ for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}
264
+ }
265
+ int Wused=0;
266
+ if(maxX>=0){
267
+ vector<char> used(maxX+1,false);
268
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}}
269
+ for(int x=0;x<=maxX;x++) if(used[x]) Wused++;
270
+ }
271
+ int Wfinal=max(0,Wused);
272
+ long long A=1LL*H*max(1,Wfinal);
273
+ return R{A,max(1,Wfinal),H,move(pl)};
274
+ };
275
+ // Gap-filling pack for small inputs - tries positions below skyline using bitmap
276
+ auto pack_gap=[&](int W,const vector<int>& o0,RNG &rng,bool randtie) -> R {
277
+ int maxHg=(int)(S/max(1,W)+W+50);
278
+ vector<vector<bool>> grid(W, vector<bool>(maxHg, false));
279
+ vector<int> h(W,-1);
280
+ long long g=-1;
281
+ vector<Pl> pl; pl.reserve(o0.size());
282
+ vector<int> o=o0;
283
+ int t2=0,nm=(int)o.size();
284
+ int maxBound=max(1,n/4);
285
+ int dynLIM=maxBound;
286
+ bool gapEnabled=true;
287
+ while(t2<nm){
288
+ int earlyBoost=(t2<nm/10)?min(3,max(1,maxBound/dynLIM)):1;
289
+ int limCnt=max(1,dynLIM*earlyBoost);
290
+ int lim=min(nm,t2+limCnt);
291
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t2; int bestid=-1;
292
+ for(int pos=t2;pos<lim;pos++){
293
+ int id=o[pos];
294
+ auto &p=ps[id];
295
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
296
+ for(int ti=0;ti<(int)p.t.size();ti++){
297
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
298
+ for(int x0=0;x0<Rpos;x0++){
299
+ // Skyline placement
300
+ int y0=0;
301
+ for(int j=0;j<tsh.w;j++){
302
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
303
+ }
304
+ // Also try gap positions (scan up to 10 rows below skyline)
305
+ int gapY=-1;
306
+ if(gapEnabled && y0>0){
307
+ int sd=min(y0,3); // Only check 3 rows below skyline
308
+ for(int gy=max(0,y0-sd);gy<y0;gy++){
309
+ bool ok=true;
310
+ for(auto &q:tsh.c){
311
+ int gx=x0+q.first,gcy=gy+q.second;
312
+ if(gcy<0||gcy>=maxHg||grid[gx][gcy]){ok=false;break;}
313
+ }
314
+ if(ok){gapY=gy;break;}
315
+ }
316
+ }
317
+ // Evaluate both positions
318
+ for(int pass=0;pass<(gapY>=0?2:1);pass++){
319
+ int yy=(pass==0)?y0:gapY;
320
+ int nhbuf[32];
321
+ int l=-1; long long dsum=0;
322
+ for(int j=0;j<tsh.w;j++){
323
+ int nh=h[x0+j];
324
+ if(tsh.hi[j]!=INT_MIN){int cand=yy+tsh.hi[j]; if(nh<cand) nh=cand;}
325
+ nhbuf[j]=nh; if(nh>l) l=nh;
326
+ }
327
+ for(int j=0;j<tsh.w;j++){int inc=nhbuf[j]-h[x0+j]; if(inc>0) dsum+=inc;}
328
+ long long dr=0;
329
+ if(x0>0){dr+=llabs((long long)nhbuf[0]-h[x0-1])-llabs((long long)h[x0]-h[x0-1]);}
330
+ for(int j=0;j<tsh.w-1;j++){dr+=llabs((long long)nhbuf[j+1]-nhbuf[j])-llabs((long long)h[x0+j+1]-h[x0+j]);}
331
+ if(x0+tsh.w<W){dr+=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1])-llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);}
332
+ long long gg=g; if(gg<l) gg=l;
333
+ bool take=false;
334
+ if(gg<bestg2) take=true;
335
+ else if(gg==bestg2){
336
+ if(dsum<bds2) take=true;
337
+ else if(dsum==bds2){if(l<bl2) take=true;
338
+ else if(l==bl2){if(dr<bdr2) take=true;
339
+ else if(dr==bdr2){if(yy<by02) take=true;
340
+ else if(yy==by02){if(x0<bx02) take=true;
341
+ else if(x0==bx02&&randtie&&rng.coin()) take=true;}}}}
342
+ }
343
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=yy;bl2=l;bds2=dsum;bdr2=dr;by02=yy;bx02=x0;}
344
+ }
345
+ }
346
+ }
347
+ if(bti2==-1) continue;
348
+ long long waste2=bds2-p.k;
349
+ bool take=false;
350
+ if(bestg2<bestg) take=true;
351
+ else if(bestg2==bestg){if(waste2<bds) take=true;
352
+ else if(waste2==bds){if(bl2<bl) take=true;
353
+ else if(bl2==bl){if(bdr2<bdr) take=true;
354
+ else if(bdr2==bdr){if(by02<by0) take=true;
355
+ else if(by02==by0){if(bx02<bx0) take=true;
356
+ else if(bx02==bx0&&randtie&&rng.coin()) take=true;}}}}}
357
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
358
+ }
359
+ if(bti==-1){t2++;continue;}
360
+ auto &tsh=ps[bestid].t[bti];
361
+ for(int j=0;j<tsh.w;j++){
362
+ int nh=h[bx+j];
363
+ if(tsh.hi[j]!=INT_MIN){int cand=by+tsh.hi[j]; if(nh<cand) nh=cand;}
364
+ h[bx+j]=nh;
365
+ }
366
+ for(auto &q:tsh.c){int gx=bx+q.first,gy=by+q.second; if(gx>=0&&gx<W&&gy>=0&&gy<maxHg) grid[gx][gy]=true;}
367
+ if(g<bl) g=bl;
368
+ pl.push_back({bestid,bti,bx,by});
369
+ if(bestpos!=t2) swap(o[t2],o[bestpos]);
370
+ t2++;
371
+ }
372
+ if((int)pl.size() < nm){
373
+ // Not all pieces placed - return failure
374
+ return R{LLONG_MAX, W, 0, {}};
375
+ }
376
+ int H=(int)g+1;
377
+ int maxX=-1;
378
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}}
379
+ int Wused=0;
380
+ if(maxX>=0){vector<char> used(maxX+1,false); for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}} for(int x=0;x<=maxX;x++) if(used[x]) Wused++;}
381
+ int Wfinal=max(0,Wused);
382
+ long long A=1LL*H*max(1,Wfinal);
383
+ return R{A,max(1,Wfinal),H,move(pl)};
384
+ };
385
+ int minW=0; for(auto &p:ps) minW=max(minW,p.minW);
386
+
387
+ // Improved width estimation
388
+ double factor;
389
+ if (S < 1000) factor = 0.4;
390
+ else if (S < 3000) factor = 0.5;
391
+ else if (S < 10000) factor = 0.27;
392
+ else if (S < 30000) factor = 0.08;
393
+ else factor = 0.01;
394
+
395
+ int base = max(minW, (int)floor(sqrt((double)S * factor)));
396
+ vector<int> Ws;
397
+ {
398
+ unordered_set<int> used; used.reserve(512);
399
+ auto addW=[&](int w){if(w<minW) w=minW; if(used.insert(w).second) Ws.push_back(w);};
400
+ addW(base);
401
+ int span=min(96,max(20,base/2));
402
+ for(int d=1;d<=span;d++){addW(base-d); addW(base+d);}
403
+ addW(minW);
404
+ addW((int)max<long long>(minW,(S+base-1)/base));
405
+ for(int m=2;m<=6;m++){addW(base*m/3); addW((int)max<long long>(minW,S/((base*m/3)?(base*m/3):1)));}
406
+ // Add sqrt(S) based widths for more square-like rectangles
407
+ int sqrtS = max(minW, (int)floor(sqrt((double)S)));
408
+ addW(sqrtS);
409
+ addW(sqrtS+1);
410
+ addW(sqrtS-1);
411
+ addW(sqrtS*2/3);
412
+ addW(sqrtS/2);
413
+ sort(Ws.begin(),Ws.end(),[&](int a,int b){int da=abs(a-base),db=abs(b-base); if(da!=db) return da<db; return a<b;});
414
+ }
415
+ long long bestA=LLONG_MAX; int bestW=0,bestH=0; R bestR; bool hasBestmine=false;
416
+ auto t0=chrono::steady_clock::now();
417
+ const double TL=1980.0;
418
+ double avg=250.0; int cnt=0;
419
+
420
+ // Prepare orderings - fewer for gap packer (slower per call)
421
+ bool useGapPacker = (S < 5000);
422
+ vector<vector<int>> base_orders;
423
+ base_orders.push_back(ord_asc_mindim());
424
+ if(!useGapPacker){
425
+ base_orders.push_back(ord_desc_area());
426
+ base_orders.push_back(ord_desc_maxdim());
427
+ base_orders.push_back(ord_desc_bbox());
428
+ base_orders.push_back(ord_flexibility());
429
+ }
430
+ auto doPack = [&](int W, const vector<int>& order, RNG& rng, bool randtie) -> R {
431
+ if(useGapPacker) return pack_gap(W, order, rng, randtie);
432
+ return pack(W, order, rng, randtie);
433
+ };
434
+
435
+ // Track best ordering index per width for perturbation
436
+ int bestOrderIdx = 0;
437
+
438
+ for(int wi=0;wi<(int)Ws.size();wi++){
439
+ auto now=chrono::steady_clock::now();
440
+ double used_time=chrono::duration<double,milli>(now-t0).count();
441
+ if(used_time+avg*1.3>TL) break;
442
+ int W=Ws[wi];
443
+
444
+ // Try each base ordering
445
+ for(int oi=0;oi<(int)base_orders.size();oi++){
446
+ now=chrono::steady_clock::now();
447
+ double used2=chrono::duration<double,milli>(now-t0).count();
448
+ if(used2+avg*1.15>TL) break;
449
+ bool randtie=(oi>=1);
450
+ auto t1=chrono::steady_clock::now();
451
+ R r=doPack(W,base_orders[oi],rng,randtie);
452
+ auto t2=chrono::steady_clock::now();
453
+ double dt=chrono::duration<double,milli>(t2-t1).count();
454
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
455
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
456
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
457
+ bestOrderIdx=oi;
458
+ }
459
+ }
460
+
461
+ // Perturbation of best ordering + random orderings
462
+ int nswaps = max(1, n/20);
463
+ int maxRandom = useGapPacker ? 1 : 4;
464
+ for(int ri=0;ri<maxRandom;ri++){
465
+ now=chrono::steady_clock::now();
466
+ double used2=chrono::duration<double,milli>(now-t0).count();
467
+ if(used2+avg*1.15>TL) break;
468
+ auto t1=chrono::steady_clock::now();
469
+ vector<int> order;
470
+ if(ri < 2) order = ord_perturb(base_orders[bestOrderIdx], nswaps);
471
+ else order = ord_random();
472
+ R r=doPack(W,order,rng,true);
473
+ auto t2=chrono::steady_clock::now();
474
+ double dt=chrono::duration<double,milli>(t2-t1).count();
475
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
476
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
477
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
478
+ }
479
+ }
480
+ }
481
+ if(!hasBestmine){
482
+ int W=max(minW,(int)floor(sqrt((double)S)));
483
+ auto o=ord_asc_mindim();
484
+ R r=pack(W,o,rng,false);
485
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
486
+ }
487
+ int maxX=-1;
488
+ for(auto &p:bestR.pl){
489
+ auto &t=ps[p.idx].t[p.ti];
490
+ for(auto &q:t.c){int x=p.x+q.first; if(x>maxX) maxX=x;}
491
+ }
492
+ vector<int> mapx(maxX+1,-1);
493
+ if(maxX>=0){
494
+ vector<char> used(maxX+1,false);
495
+ for(auto &p:bestR.pl){
496
+ auto &t=ps[p.idx].t[p.ti];
497
+ for(auto &q:t.c){used[p.x+q.first]=true;}
498
+ }
499
+ int cur=0;
500
+ for(int x=0;x<=maxX;x++) if(used[x]) mapx[x]=cur++;
501
+ }
502
+ vector<array<int,4>> ans(n,{0,0,0,0});
503
+ for(auto &p:bestR.pl){
504
+ auto &t=ps[p.idx].t[p.ti];
505
+ int bx = (mapx.empty()?p.x:mapx[p.x]);
506
+ int Xi = bx - t.minx;
507
+ int Yi = p.y - t.miny;
508
+ int Ri = (4 - (t.r%4) + 4) % 4;
509
+ int Fi = t.f;
510
+ ans[p.idx]={Xi,Yi,Ri,Fi};
511
+ }
512
+ cout<<bestR.W<<" "<<bestR.H<<"\n";
513
+ for(int i=0;i<n;i++){
514
+ cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<"\n";
515
+ }
516
+ return 0;
517
+ }
docker_space/frontier_cs_0_polyomino_ev2/logs/gen_33.cpp ADDED
@@ -0,0 +1,535 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Gen 1: Multiple orderings + improved width search
3
+ Based on reference.cpp with:
4
+ - 4 ordering strategies (ascending min dim, descending area, descending max dim, random)
5
+ - Each width tries all orderings (time permitting)
6
+ - Better width candidate generation
7
+ */
8
+ #include <bits/stdc++.h>
9
+ using namespace std;
10
+ struct T{int w,h;vector<pair<int,int>> c;vector<int> lo,hi;int r,f,minx,miny;};
11
+ struct P{int id,k;vector<pair<int,int>> b;vector<T> t;int minW=1e9,minH=1e9,minA=1e9;};
12
+ struct Pl{int idx,ti,x,y;};
13
+ struct R{long long A;int W,H;vector<Pl> pl;};
14
+ struct RNG{unsigned long long s;RNG(unsigned long long x){s=x?x:1;}inline unsigned long long nxt(){s^=s<<7;s^=s>>9;return s;}inline int rint(int n){return (int)(nxt()%n);}inline bool coin(){return nxt()&1;}};
15
+ static inline pair<int,int> rotp(pair<int,int> p,int r){if(r==0)return p; if(r==1)return make_pair(-p.second,p.first); if(r==2)return make_pair(-p.first,-p.second); return make_pair(p.second,-p.first);}
16
+ int main(){
17
+ ios::sync_with_stdio(false);
18
+ cin.tie(nullptr);
19
+ int n; if(!(cin>>n)) return 0;
20
+ vector<P> ps(n); long long S=0;
21
+ for(int i=0;i<n;i++){
22
+ int k;cin>>k; ps[i].id=i+1; ps[i].k=k; ps[i].b.resize(k);
23
+ for(int j=0;j<k;j++){int x,y;cin>>x>>y; ps[i].b[j]={x,y};}
24
+ S+=k;
25
+ }
26
+ for(int i=0;i<n;i++){
27
+ auto &p=ps[i]; unordered_set<string> seen; seen.reserve(32);
28
+ for(int rf=0;rf<2;rf++){
29
+ vector<pair<int,int>> src=p.b; if(rf){for(auto &q:src) q.first=-q.first;}
30
+ for(int r=0;r<4;r++){
31
+ vector<pair<int,int>> v=src; for(auto &q:v) q=rotp(q,r);
32
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
33
+ for(auto &q:v){minx=min(minx,q.first);miny=min(miny,q.second);maxx=max(maxx,q.first);maxy=max(maxy,q.second);}
34
+ vector<pair<int,int>> v2=v; for(auto &q:v2){q.first-=minx;q.second-=miny;}
35
+ sort(v2.begin(),v2.end());
36
+ string key; key.reserve(v2.size()*8);
37
+ for(auto &q:v2){key.append(to_string(q.first));key.push_back(',');key.append(to_string(q.second));key.push_back(';');}
38
+ if(seen.insert(key).second){
39
+ T t; t.w=maxx-minx+1; t.h=maxy-miny+1; t.c=v2; t.r=r; t.f=rf; t.minx=minx; t.miny=miny;
40
+ t.lo.assign(t.w,INT_MAX); t.hi.assign(t.w,INT_MIN);
41
+ for(auto &q:v2){int x=q.first,y=q.second; if(t.lo[x]>y) t.lo[x]=y; if(t.hi[x]<y) t.hi[x]=y;}
42
+ p.t.push_back(move(t));
43
+ }
44
+ }
45
+ }
46
+ for(auto &t:p.t){p.minW=min(p.minW,t.w); p.minH=min(p.minH,t.h); p.minA=min(p.minA,t.w*t.h);}
47
+ if(p.t.empty()){T t; t.w=1;t.h=1;t.c={{0,0}};t.lo={0};t.hi={0};t.r=0;t.f=0;t.minx=0;t.miny=0;p.t.push_back(t);p.minW=1;p.minH=1;p.minA=1;}
48
+ }
49
+ vector<int> idx(n); iota(idx.begin(),idx.end(),0);
50
+ unsigned long long seed=((unsigned long long)chrono::high_resolution_clock::now().time_since_epoch().count()) ^ (S<<1) ^ (unsigned long long)(n*1469598103934665603ULL);
51
+ RNG rng(seed);
52
+
53
+ // Multiple ordering strategies
54
+ auto ord_asc_mindim = [&]() {
55
+ vector<int> res = idx;
56
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
57
+ int da = min(ps[a].minW, ps[a].minH);
58
+ int db = min(ps[b].minW, ps[b].minH);
59
+ if (da != db) return da < db;
60
+ if (ps[a].k != ps[b].k) return ps[a].k < ps[b].k;
61
+ return ps[a].id > ps[b].id;
62
+ });
63
+ return res;
64
+ };
65
+ auto ord_desc_area = [&]() {
66
+ vector<int> res = idx;
67
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
68
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
69
+ int da = min(ps[a].minW, ps[a].minH);
70
+ int db = min(ps[b].minW, ps[b].minH);
71
+ if (da != db) return da > db;
72
+ return ps[a].id < ps[b].id;
73
+ });
74
+ return res;
75
+ };
76
+ auto ord_desc_maxdim = [&]() {
77
+ vector<int> res = idx;
78
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
79
+ int da = max(ps[a].minW, ps[a].minH);
80
+ int db = max(ps[b].minW, ps[b].minH);
81
+ if (da != db) return da > db;
82
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
83
+ return ps[a].id < ps[b].id;
84
+ });
85
+ return res;
86
+ };
87
+ auto ord_desc_bbox = [&]() {
88
+ vector<int> res = idx;
89
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
90
+ if (ps[a].minA != ps[b].minA) return ps[a].minA > ps[b].minA;
91
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
92
+ return ps[a].id < ps[b].id;
93
+ });
94
+ return res;
95
+ };
96
+ auto ord_random = [&]() {
97
+ vector<int> res = idx;
98
+ for(int i=n-1;i>0;i--){
99
+ int j=rng.rint(i+1);
100
+ swap(res[i],res[j]);
101
+ }
102
+ return res;
103
+ };
104
+ // Perturb a given ordering by making random swaps
105
+ auto ord_perturb = [&](const vector<int>& base_ord, int nswaps) {
106
+ vector<int> res = base_ord;
107
+ for(int i=0;i<nswaps;i++){
108
+ int a=rng.rint(n), b=rng.rint(n);
109
+ swap(res[a],res[b]);
110
+ }
111
+ return res;
112
+ };
113
+ // Sort by flexibility (fewer variants first = harder to place)
114
+ auto ord_flexibility = [&]() {
115
+ vector<int> res = idx;
116
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
117
+ int va=(int)ps[a].t.size(), vb=(int)ps[b].t.size();
118
+ if(va!=vb) return va<vb;
119
+ if(ps[a].k!=ps[b].k) return ps[a].k>ps[b].k;
120
+ return ps[a].id<ps[b].id;
121
+ });
122
+ return res;
123
+ };
124
+
125
+ auto pack=[&](int W,const vector<int>& o0,RNG &rng,bool randtie){
126
+ vector<int> h(W,-1);
127
+ long long g=-1;
128
+ vector<Pl> pl; pl.reserve(o0.size());
129
+ vector<int> o=o0;
130
+ int t=0,nm=(int)o.size();
131
+ bool big=S>7000;
132
+ int maxBound=max(1,n/4);
133
+ int expLIM=min(maxBound,(int)(350000/max(1LL,S-3500)));
134
+ int dynLIM=big?expLIM:maxBound;
135
+ auto tStart=chrono::steady_clock::now();
136
+ auto batchStart=tStart;
137
+ long long TLms=big?1900:LLONG_MAX/4;
138
+ int stepCnt=0;
139
+ while(t<nm){
140
+ // Increase lookahead for early pieces (they have most impact)
141
+ int earlyBoost = (t < nm/10) ? min(3, max(1, maxBound/dynLIM)) : 1;
142
+ int limCnt=max(1,dynLIM * earlyBoost);
143
+ int lim=min(nm,t+limCnt);
144
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t; int bestid=-1;
145
+ for(int pos=t;pos<lim;pos++){
146
+ int id=o[pos];
147
+ auto &p=ps[id];
148
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
149
+ for(int ti=0;ti<(int)p.t.size();ti++){
150
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
151
+ for(int x0=0;x0<Rpos;x0++){
152
+ int y0=0;
153
+ for(int j=0;j<tsh.w;j++){
154
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
155
+ }
156
+ int nhbuf[32];
157
+ int l=-1; long long dsum=0;
158
+ for(int j=0;j<tsh.w;j++){
159
+ int nh=h[x0+j];
160
+ if(tsh.hi[j]!=INT_MIN){
161
+ int cand=y0+tsh.hi[j];
162
+ if(nh<cand) nh=cand;
163
+ }
164
+ nhbuf[j]=nh;
165
+ if(nh>l) l=nh;
166
+ }
167
+ for(int j=0;j<tsh.w;j++){
168
+ int inc=nhbuf[j]-h[x0+j];
169
+ if(inc>0) dsum+=inc;
170
+ }
171
+ long long dr=0;
172
+ if(x0>0){
173
+ long long old=llabs((long long)h[x0]-h[x0-1]);
174
+ long long nw=llabs((long long)nhbuf[0]-h[x0-1]);
175
+ dr+=nw-old;
176
+ }
177
+ for(int j=0;j<tsh.w-1;j++){
178
+ long long old=llabs((long long)h[x0+j+1]-h[x0+j]);
179
+ long long nw=llabs((long long)nhbuf[j+1]-nhbuf[j]);
180
+ dr+=nw-old;
181
+ }
182
+ if(x0+tsh.w<W){
183
+ long long old=llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);
184
+ long long nw=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1]);
185
+ dr+=nw-old;
186
+ }
187
+ long long gg=g; if(gg<l) gg=l;
188
+ bool take=false;
189
+ if(gg<bestg2) take=true;
190
+ else if(gg==bestg2){
191
+ if(dsum<bds2) take=true;
192
+ else if(dsum==bds2){
193
+ if(l<bl2) take=true;
194
+ else if(l==bl2){
195
+ if(dr<bdr2) take=true;
196
+ else if(dr==bdr2){
197
+ if(y0<by02) take=true;
198
+ else if(y0==by02){
199
+ if(x0<bx02) take=true;
200
+ else if(x0==bx02 && randtie && rng.coin()) take=true;
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
206
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=y0;bl2=l;bds2=dsum;bdr2=dr;by02=y0;bx02=x0;}
207
+ }
208
+ }
209
+ if(bti2==-1) continue;
210
+ // Use waste = dsum - k for between-piece comparison (accounts for piece size)
211
+ long long waste2 = bds2 - p.k;
212
+ bool take=false;
213
+ if(bestg2<bestg) take=true;
214
+ else if(bestg2==bestg){
215
+ if(waste2<bds) take=true;
216
+ else if(waste2==bds){
217
+ if(bl2<bl) take=true;
218
+ else if(bl2==bl){
219
+ if(bdr2<bdr) take=true;
220
+ else if(bdr2==bdr){
221
+ if(by02<by0) take=true;
222
+ else if(by02==by0){
223
+ if(bx02<bx0) take=true;
224
+ else if(bx02==bx0 && randtie && rng.coin()) take=true;
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
231
+ }
232
+ if(bti==-1){t++;stepCnt++;if(big&&stepCnt==5){auto now=chrono::steady_clock::now(); auto elapsed=chrono::duration<double,milli>(now-tStart).count(); auto batch=chrono::duration<double,milli>(now-batchStart).count(); double remT=max(0.0,TLms-elapsed); int remSteps=max(1,nm-t); double budget=remT*5.0/remSteps; if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1); batchStart=now; stepCnt=0;} continue;}
233
+ auto &tsh=ps[bestid].t[bti];
234
+ for(int j=0;j<tsh.w;j++){
235
+ int nh=h[bx+j];
236
+ if(tsh.hi[j]!=INT_MIN){
237
+ int cand=by+tsh.hi[j];
238
+ if(nh<cand) nh=cand;
239
+ }
240
+ h[bx+j]=nh;
241
+ }
242
+ if(g<bl) g=bl;
243
+ pl.push_back({bestid,bti,bx,by});
244
+ if(bestpos!=t) swap(o[t],o[bestpos]);
245
+ t++;
246
+ stepCnt++;
247
+ if(big&&stepCnt==5){
248
+ auto now=chrono::steady_clock::now();
249
+ auto elapsed=chrono::duration<double,milli>(now-tStart).count();
250
+ auto batch=chrono::duration<double,milli>(now-batchStart).count();
251
+ double remT=max(0.0,TLms-elapsed);
252
+ int remSteps=max(1,nm-t);
253
+ double budget=remT*5.0/remSteps;
254
+ if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
255
+ batchStart=now;
256
+ stepCnt=0;
257
+ }
258
+ }
259
+ int H=(int)g+1;
260
+ int maxX=-1;
261
+ for(auto &pp:pl){
262
+ auto &t=ps[pp.idx].t[pp.ti];
263
+ for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}
264
+ }
265
+ int Wused=0;
266
+ if(maxX>=0){
267
+ vector<char> used(maxX+1,false);
268
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}}
269
+ for(int x=0;x<=maxX;x++) if(used[x]) Wused++;
270
+ }
271
+ int Wfinal=max(0,Wused);
272
+ long long A=1LL*H*max(1,Wfinal);
273
+ return R{A,max(1,Wfinal),H,move(pl)};
274
+ };
275
+ // Gap-filling pack for small inputs - tries positions below skyline using bitmap
276
+ auto pack_gap=[&](int W,const vector<int>& o0,RNG &rng,bool randtie) -> R {
277
+ int maxHg=(int)(S/max(1,W)+W+50);
278
+ vector<vector<bool>> grid(W, vector<bool>(maxHg, false));
279
+ vector<int> h(W,-1);
280
+ long long g=-1;
281
+ vector<Pl> pl; pl.reserve(o0.size());
282
+ vector<int> o=o0;
283
+ int t2=0,nm=(int)o.size();
284
+ bool big2=(S>7000);
285
+ int maxBound=max(1,n/4);
286
+ int expLIM2=min(maxBound,(int)(350000/max(1LL,S-3500)));
287
+ int dynLIM=big2?expLIM2:maxBound;
288
+ bool gapEnabled=true;
289
+ auto gpTStart=chrono::steady_clock::now();
290
+ auto gpBatchStart=gpTStart;
291
+ long long gpTLms=big2?1800:LLONG_MAX/4;
292
+ int gpStepCnt=0;
293
+ while(t2<nm){
294
+ int earlyBoost=(t2<nm/10)?min(3,max(1,maxBound/max(1,dynLIM))):1;
295
+ int limCnt=max(1,dynLIM*earlyBoost);
296
+ int lim=min(nm,t2+limCnt);
297
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t2; int bestid=-1;
298
+ for(int pos=t2;pos<lim;pos++){
299
+ int id=o[pos];
300
+ auto &p=ps[id];
301
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
302
+ for(int ti=0;ti<(int)p.t.size();ti++){
303
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
304
+ for(int x0=0;x0<Rpos;x0++){
305
+ // Skyline placement
306
+ int y0=0;
307
+ for(int j=0;j<tsh.w;j++){
308
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
309
+ }
310
+ // Also try gap positions (scan up to 10 rows below skyline)
311
+ int gapY=-1;
312
+ if(gapEnabled && y0>0){
313
+ int sd=min(y0,3); // Only check 3 rows below skyline
314
+ for(int gy=max(0,y0-sd);gy<y0;gy++){
315
+ bool ok=true;
316
+ for(auto &q:tsh.c){
317
+ int gx=x0+q.first,gcy=gy+q.second;
318
+ if(gcy<0||gcy>=maxHg||grid[gx][gcy]){ok=false;break;}
319
+ }
320
+ if(ok){gapY=gy;break;}
321
+ }
322
+ }
323
+ // Evaluate both positions
324
+ for(int pass=0;pass<(gapY>=0?2:1);pass++){
325
+ int yy=(pass==0)?y0:gapY;
326
+ int nhbuf[32];
327
+ int l=-1; long long dsum=0;
328
+ for(int j=0;j<tsh.w;j++){
329
+ int nh=h[x0+j];
330
+ if(tsh.hi[j]!=INT_MIN){int cand=yy+tsh.hi[j]; if(nh<cand) nh=cand;}
331
+ nhbuf[j]=nh; if(nh>l) l=nh;
332
+ }
333
+ for(int j=0;j<tsh.w;j++){int inc=nhbuf[j]-h[x0+j]; if(inc>0) dsum+=inc;}
334
+ long long dr=0;
335
+ if(x0>0){dr+=llabs((long long)nhbuf[0]-h[x0-1])-llabs((long long)h[x0]-h[x0-1]);}
336
+ for(int j=0;j<tsh.w-1;j++){dr+=llabs((long long)nhbuf[j+1]-nhbuf[j])-llabs((long long)h[x0+j+1]-h[x0+j]);}
337
+ if(x0+tsh.w<W){dr+=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1])-llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);}
338
+ long long gg=g; if(gg<l) gg=l;
339
+ bool take=false;
340
+ if(gg<bestg2) take=true;
341
+ else if(gg==bestg2){
342
+ if(dsum<bds2) take=true;
343
+ else if(dsum==bds2){if(l<bl2) take=true;
344
+ else if(l==bl2){if(dr<bdr2) take=true;
345
+ else if(dr==bdr2){if(yy<by02) take=true;
346
+ else if(yy==by02){if(x0<bx02) take=true;
347
+ else if(x0==bx02&&randtie&&rng.coin()) take=true;}}}}
348
+ }
349
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=yy;bl2=l;bds2=dsum;bdr2=dr;by02=yy;bx02=x0;}
350
+ }
351
+ }
352
+ }
353
+ if(bti2==-1) continue;
354
+ long long waste2=bds2-p.k;
355
+ bool take=false;
356
+ if(bestg2<bestg) take=true;
357
+ else if(bestg2==bestg){if(waste2<bds) take=true;
358
+ else if(waste2==bds){if(bl2<bl) take=true;
359
+ else if(bl2==bl){if(bdr2<bdr) take=true;
360
+ else if(bdr2==bdr){if(by02<by0) take=true;
361
+ else if(by02==by0){if(bx02<bx0) take=true;
362
+ else if(bx02==bx0&&randtie&&rng.coin()) take=true;}}}}}
363
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
364
+ }
365
+ if(bti==-1){t2++;continue;}
366
+ auto &tsh=ps[bestid].t[bti];
367
+ for(int j=0;j<tsh.w;j++){
368
+ int nh=h[bx+j];
369
+ if(tsh.hi[j]!=INT_MIN){int cand=by+tsh.hi[j]; if(nh<cand) nh=cand;}
370
+ h[bx+j]=nh;
371
+ }
372
+ for(auto &q:tsh.c){int gx=bx+q.first,gy=by+q.second; if(gx>=0&&gx<W&&gy>=0&&gy<maxHg) grid[gx][gy]=true;}
373
+ if(g<bl) g=bl;
374
+ pl.push_back({bestid,bti,bx,by});
375
+ if(bestpos!=t2) swap(o[t2],o[bestpos]);
376
+ t2++;
377
+ gpStepCnt++;
378
+ if(big2&&gpStepCnt==5){
379
+ auto gpNow=chrono::steady_clock::now();
380
+ auto gpElapsed=chrono::duration<double,milli>(gpNow-gpTStart).count();
381
+ auto gpBatch=chrono::duration<double,milli>(gpNow-gpBatchStart).count();
382
+ double gpRemT=max(0.0,(double)gpTLms-gpElapsed);
383
+ int gpRemSteps=max(1,nm-t2);
384
+ double gpBudget=gpRemT*5.0/gpRemSteps;
385
+ if(gpBatch<gpBudget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
386
+ gpBatchStart=gpNow;
387
+ gpStepCnt=0;
388
+ }
389
+ }
390
+ if((int)pl.size() < nm){
391
+ // Not all pieces placed - return failure
392
+ return R{LLONG_MAX, W, 0, {}};
393
+ }
394
+ int H=(int)g+1;
395
+ int maxX=-1;
396
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}}
397
+ int Wused=0;
398
+ if(maxX>=0){vector<char> used(maxX+1,false); for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}} for(int x=0;x<=maxX;x++) if(used[x]) Wused++;}
399
+ int Wfinal=max(0,Wused);
400
+ long long A=1LL*H*max(1,Wfinal);
401
+ return R{A,max(1,Wfinal),H,move(pl)};
402
+ };
403
+ int minW=0; for(auto &p:ps) minW=max(minW,p.minW);
404
+
405
+ // Improved width estimation
406
+ double factor;
407
+ if (S < 1000) factor = 0.4;
408
+ else if (S < 3000) factor = 0.5;
409
+ else if (S < 10000) factor = 0.27;
410
+ else if (S < 30000) factor = 0.08;
411
+ else factor = 0.01;
412
+
413
+ int base = max(minW, (int)floor(sqrt((double)S * factor)));
414
+ vector<int> Ws;
415
+ {
416
+ unordered_set<int> used; used.reserve(512);
417
+ auto addW=[&](int w){if(w<minW) w=minW; if(used.insert(w).second) Ws.push_back(w);};
418
+ addW(base);
419
+ int span=min(96,max(20,base/2));
420
+ for(int d=1;d<=span;d++){addW(base-d); addW(base+d);}
421
+ addW(minW);
422
+ addW((int)max<long long>(minW,(S+base-1)/base));
423
+ for(int m=2;m<=6;m++){addW(base*m/3); addW((int)max<long long>(minW,S/((base*m/3)?(base*m/3):1)));}
424
+ // Add sqrt(S) based widths for more square-like rectangles
425
+ int sqrtS = max(minW, (int)floor(sqrt((double)S)));
426
+ addW(sqrtS);
427
+ addW(sqrtS+1);
428
+ addW(sqrtS-1);
429
+ addW(sqrtS*2/3);
430
+ addW(sqrtS/2);
431
+ sort(Ws.begin(),Ws.end(),[&](int a,int b){int da=abs(a-base),db=abs(b-base); if(da!=db) return da<db; return a<b;});
432
+ }
433
+ long long bestA=LLONG_MAX; int bestW=0,bestH=0; R bestR; bool hasBestmine=false;
434
+ auto t0=chrono::steady_clock::now();
435
+ const double TL=1980.0;
436
+ double avg=250.0; int cnt=0;
437
+
438
+ // Prepare orderings - fewer for gap packer (slower per call)
439
+ bool useGapPacker = (S < 12000);
440
+ vector<vector<int>> base_orders;
441
+ base_orders.push_back(ord_asc_mindim());
442
+ if(!useGapPacker){
443
+ base_orders.push_back(ord_desc_area());
444
+ base_orders.push_back(ord_desc_maxdim());
445
+ base_orders.push_back(ord_desc_bbox());
446
+ base_orders.push_back(ord_flexibility());
447
+ }
448
+ auto doPack = [&](int W, const vector<int>& order, RNG& rng, bool randtie) -> R {
449
+ if(useGapPacker) return pack_gap(W, order, rng, randtie);
450
+ return pack(W, order, rng, randtie);
451
+ };
452
+
453
+ // Track best ordering index per width for perturbation
454
+ int bestOrderIdx = 0;
455
+
456
+ for(int wi=0;wi<(int)Ws.size();wi++){
457
+ auto now=chrono::steady_clock::now();
458
+ double used_time=chrono::duration<double,milli>(now-t0).count();
459
+ if(used_time+avg*1.3>TL) break;
460
+ int W=Ws[wi];
461
+
462
+ // Try each base ordering
463
+ for(int oi=0;oi<(int)base_orders.size();oi++){
464
+ now=chrono::steady_clock::now();
465
+ double used2=chrono::duration<double,milli>(now-t0).count();
466
+ if(used2+avg*1.15>TL) break;
467
+ bool randtie=(oi>=1);
468
+ auto t1=chrono::steady_clock::now();
469
+ R r=doPack(W,base_orders[oi],rng,randtie);
470
+ auto t2=chrono::steady_clock::now();
471
+ double dt=chrono::duration<double,milli>(t2-t1).count();
472
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
473
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
474
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
475
+ bestOrderIdx=oi;
476
+ }
477
+ }
478
+
479
+ // Perturbation of best ordering + random orderings
480
+ int nswaps = max(1, n/20);
481
+ int maxRandom = useGapPacker ? 1 : 4;
482
+ for(int ri=0;ri<maxRandom;ri++){
483
+ now=chrono::steady_clock::now();
484
+ double used2=chrono::duration<double,milli>(now-t0).count();
485
+ if(used2+avg*1.15>TL) break;
486
+ auto t1=chrono::steady_clock::now();
487
+ vector<int> order;
488
+ if(ri < 2) order = ord_perturb(base_orders[bestOrderIdx], nswaps);
489
+ else order = ord_random();
490
+ R r=doPack(W,order,rng,true);
491
+ auto t2=chrono::steady_clock::now();
492
+ double dt=chrono::duration<double,milli>(t2-t1).count();
493
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
494
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
495
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
496
+ }
497
+ }
498
+ }
499
+ if(!hasBestmine){
500
+ int W=max(minW,(int)floor(sqrt((double)S)));
501
+ auto o=ord_asc_mindim();
502
+ R r=pack(W,o,rng,false);
503
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
504
+ }
505
+ int maxX=-1;
506
+ for(auto &p:bestR.pl){
507
+ auto &t=ps[p.idx].t[p.ti];
508
+ for(auto &q:t.c){int x=p.x+q.first; if(x>maxX) maxX=x;}
509
+ }
510
+ vector<int> mapx(maxX+1,-1);
511
+ if(maxX>=0){
512
+ vector<char> used(maxX+1,false);
513
+ for(auto &p:bestR.pl){
514
+ auto &t=ps[p.idx].t[p.ti];
515
+ for(auto &q:t.c){used[p.x+q.first]=true;}
516
+ }
517
+ int cur=0;
518
+ for(int x=0;x<=maxX;x++) if(used[x]) mapx[x]=cur++;
519
+ }
520
+ vector<array<int,4>> ans(n,{0,0,0,0});
521
+ for(auto &p:bestR.pl){
522
+ auto &t=ps[p.idx].t[p.ti];
523
+ int bx = (mapx.empty()?p.x:mapx[p.x]);
524
+ int Xi = bx - t.minx;
525
+ int Yi = p.y - t.miny;
526
+ int Ri = (4 - (t.r%4) + 4) % 4;
527
+ int Fi = t.f;
528
+ ans[p.idx]={Xi,Yi,Ri,Fi};
529
+ }
530
+ cout<<bestR.W<<" "<<bestR.H<<"\n";
531
+ for(int i=0;i<n;i++){
532
+ cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<"\n";
533
+ }
534
+ return 0;
535
+ }
docker_space/frontier_cs_0_polyomino_ev2/logs/gen_5.cpp ADDED
@@ -0,0 +1,399 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Gen 1: Multiple orderings + improved width search
3
+ Based on reference.cpp with:
4
+ - 4 ordering strategies (ascending min dim, descending area, descending max dim, random)
5
+ - Each width tries all orderings (time permitting)
6
+ - Better width candidate generation
7
+ */
8
+ #include <bits/stdc++.h>
9
+ using namespace std;
10
+ struct T{int w,h;vector<pair<int,int>> c;vector<int> lo,hi;int r,f,minx,miny;};
11
+ struct P{int id,k;vector<pair<int,int>> b;vector<T> t;int minW=1e9,minH=1e9,minA=1e9;};
12
+ struct Pl{int idx,ti,x,y;};
13
+ struct R{long long A;int W,H;vector<Pl> pl;};
14
+ struct RNG{unsigned long long s;RNG(unsigned long long x){s=x?x:1;}inline unsigned long long nxt(){s^=s<<7;s^=s>>9;return s;}inline int rint(int n){return (int)(nxt()%n);}inline bool coin(){return nxt()&1;}};
15
+ static inline pair<int,int> rotp(pair<int,int> p,int r){if(r==0)return p; if(r==1)return make_pair(-p.second,p.first); if(r==2)return make_pair(-p.first,-p.second); return make_pair(p.second,-p.first);}
16
+ int main(){
17
+ ios::sync_with_stdio(false);
18
+ cin.tie(nullptr);
19
+ int n; if(!(cin>>n)) return 0;
20
+ vector<P> ps(n); long long S=0;
21
+ for(int i=0;i<n;i++){
22
+ int k;cin>>k; ps[i].id=i+1; ps[i].k=k; ps[i].b.resize(k);
23
+ for(int j=0;j<k;j++){int x,y;cin>>x>>y; ps[i].b[j]={x,y};}
24
+ S+=k;
25
+ }
26
+ for(int i=0;i<n;i++){
27
+ auto &p=ps[i]; unordered_set<string> seen; seen.reserve(32);
28
+ for(int rf=0;rf<2;rf++){
29
+ vector<pair<int,int>> src=p.b; if(rf){for(auto &q:src) q.first=-q.first;}
30
+ for(int r=0;r<4;r++){
31
+ vector<pair<int,int>> v=src; for(auto &q:v) q=rotp(q,r);
32
+ int minx=INT_MAX,miny=INT_MAX,maxx=INT_MIN,maxy=INT_MIN;
33
+ for(auto &q:v){minx=min(minx,q.first);miny=min(miny,q.second);maxx=max(maxx,q.first);maxy=max(maxy,q.second);}
34
+ vector<pair<int,int>> v2=v; for(auto &q:v2){q.first-=minx;q.second-=miny;}
35
+ sort(v2.begin(),v2.end());
36
+ string key; key.reserve(v2.size()*8);
37
+ for(auto &q:v2){key.append(to_string(q.first));key.push_back(',');key.append(to_string(q.second));key.push_back(';');}
38
+ if(seen.insert(key).second){
39
+ T t; t.w=maxx-minx+1; t.h=maxy-miny+1; t.c=v2; t.r=r; t.f=rf; t.minx=minx; t.miny=miny;
40
+ t.lo.assign(t.w,INT_MAX); t.hi.assign(t.w,INT_MIN);
41
+ for(auto &q:v2){int x=q.first,y=q.second; if(t.lo[x]>y) t.lo[x]=y; if(t.hi[x]<y) t.hi[x]=y;}
42
+ p.t.push_back(move(t));
43
+ }
44
+ }
45
+ }
46
+ for(auto &t:p.t){p.minW=min(p.minW,t.w); p.minH=min(p.minH,t.h); p.minA=min(p.minA,t.w*t.h);}
47
+ if(p.t.empty()){T t; t.w=1;t.h=1;t.c={{0,0}};t.lo={0};t.hi={0};t.r=0;t.f=0;t.minx=0;t.miny=0;p.t.push_back(t);p.minW=1;p.minH=1;p.minA=1;}
48
+ }
49
+ vector<int> idx(n); iota(idx.begin(),idx.end(),0);
50
+ unsigned long long seed=((unsigned long long)chrono::high_resolution_clock::now().time_since_epoch().count()) ^ (S<<1) ^ (unsigned long long)(n*1469598103934665603ULL);
51
+ RNG rng(seed);
52
+
53
+ // Multiple ordering strategies
54
+ auto ord_asc_mindim = [&]() {
55
+ vector<int> res = idx;
56
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
57
+ int da = min(ps[a].minW, ps[a].minH);
58
+ int db = min(ps[b].minW, ps[b].minH);
59
+ if (da != db) return da < db;
60
+ if (ps[a].k != ps[b].k) return ps[a].k < ps[b].k;
61
+ return ps[a].id > ps[b].id;
62
+ });
63
+ return res;
64
+ };
65
+ auto ord_desc_area = [&]() {
66
+ vector<int> res = idx;
67
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
68
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
69
+ int da = min(ps[a].minW, ps[a].minH);
70
+ int db = min(ps[b].minW, ps[b].minH);
71
+ if (da != db) return da > db;
72
+ return ps[a].id < ps[b].id;
73
+ });
74
+ return res;
75
+ };
76
+ auto ord_desc_maxdim = [&]() {
77
+ vector<int> res = idx;
78
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
79
+ int da = max(ps[a].minW, ps[a].minH);
80
+ int db = max(ps[b].minW, ps[b].minH);
81
+ if (da != db) return da > db;
82
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
83
+ return ps[a].id < ps[b].id;
84
+ });
85
+ return res;
86
+ };
87
+ auto ord_desc_bbox = [&]() {
88
+ vector<int> res = idx;
89
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
90
+ if (ps[a].minA != ps[b].minA) return ps[a].minA > ps[b].minA;
91
+ if (ps[a].k != ps[b].k) return ps[a].k > ps[b].k;
92
+ return ps[a].id < ps[b].id;
93
+ });
94
+ return res;
95
+ };
96
+ auto ord_random = [&]() {
97
+ vector<int> res = idx;
98
+ for(int i=n-1;i>0;i--){
99
+ int j=rng.rint(i+1);
100
+ swap(res[i],res[j]);
101
+ }
102
+ return res;
103
+ };
104
+ // Perturb a given ordering by making random swaps
105
+ auto ord_perturb = [&](const vector<int>& base_ord, int nswaps) {
106
+ vector<int> res = base_ord;
107
+ for(int i=0;i<nswaps;i++){
108
+ int a=rng.rint(n), b=rng.rint(n);
109
+ swap(res[a],res[b]);
110
+ }
111
+ return res;
112
+ };
113
+ // Sort by flexibility (fewer variants first = harder to place)
114
+ auto ord_flexibility = [&]() {
115
+ vector<int> res = idx;
116
+ stable_sort(res.begin(), res.end(), [&](int a, int b) {
117
+ int va=(int)ps[a].t.size(), vb=(int)ps[b].t.size();
118
+ if(va!=vb) return va<vb;
119
+ if(ps[a].k!=ps[b].k) return ps[a].k>ps[b].k;
120
+ return ps[a].id<ps[b].id;
121
+ });
122
+ return res;
123
+ };
124
+
125
+ auto pack=[&](int W,const vector<int>& o0,RNG &rng,bool randtie){
126
+ vector<int> h(W,-1);
127
+ long long g=-1;
128
+ vector<Pl> pl; pl.reserve(o0.size());
129
+ vector<int> o=o0;
130
+ int t=0,nm=(int)o.size();
131
+ bool big=S>7000;
132
+ int maxBound=max(1,n/4);
133
+ int expLIM=min(maxBound,(int)(350000/max(1LL,S-3500)));
134
+ int dynLIM=big?expLIM:maxBound;
135
+ auto tStart=chrono::steady_clock::now();
136
+ auto batchStart=tStart;
137
+ long long TLms=big?1900:LLONG_MAX/4;
138
+ int stepCnt=0;
139
+ while(t<nm){
140
+ // Increase lookahead for early pieces (they have most impact)
141
+ int earlyBoost = (t < nm/10) ? min(3, max(1, maxBound/dynLIM)) : 1;
142
+ int limCnt=max(1,dynLIM * earlyBoost);
143
+ int lim=min(nm,t+limCnt);
144
+ long long bestg=LLONG_MAX; int bti=-1,bx=0,by=0,bl=INT_MAX; long long bds=LLONG_MAX; long long bdr=LLONG_MAX; int by0=INT_MAX,bx0=INT_MAX; int bestpos=t; int bestid=-1;
145
+ for(int pos=t;pos<lim;pos++){
146
+ int id=o[pos];
147
+ auto &p=ps[id];
148
+ long long bestg2=LLONG_MAX; int bti2=-1,bx2=0,by2=0,bl2=INT_MAX; long long bds2=LLONG_MAX; long long bdr2=LLONG_MAX; int by02=INT_MAX,bx02=INT_MAX;
149
+ for(int ti=0;ti<(int)p.t.size();ti++){
150
+ auto &tsh=p.t[ti]; if(tsh.w>W) continue; int Rpos=W-tsh.w+1;
151
+ for(int x0=0;x0<Rpos;x0++){
152
+ int y0=0;
153
+ for(int j=0;j<tsh.w;j++){
154
+ if(tsh.lo[j]!=INT_MAX){int v=h[x0+j]-tsh.lo[j]+1; if(v>y0) y0=v;}
155
+ }
156
+ int nhbuf[32];
157
+ int l=-1; long long dsum=0;
158
+ for(int j=0;j<tsh.w;j++){
159
+ int nh=h[x0+j];
160
+ if(tsh.hi[j]!=INT_MIN){
161
+ int cand=y0+tsh.hi[j];
162
+ if(nh<cand) nh=cand;
163
+ }
164
+ nhbuf[j]=nh;
165
+ if(nh>l) l=nh;
166
+ }
167
+ for(int j=0;j<tsh.w;j++){
168
+ int inc=nhbuf[j]-h[x0+j];
169
+ if(inc>0) dsum+=inc;
170
+ }
171
+ long long dr=0;
172
+ if(x0>0){
173
+ long long old=llabs((long long)h[x0]-h[x0-1]);
174
+ long long nw=llabs((long long)nhbuf[0]-h[x0-1]);
175
+ dr+=nw-old;
176
+ }
177
+ for(int j=0;j<tsh.w-1;j++){
178
+ long long old=llabs((long long)h[x0+j+1]-h[x0+j]);
179
+ long long nw=llabs((long long)nhbuf[j+1]-nhbuf[j]);
180
+ dr+=nw-old;
181
+ }
182
+ if(x0+tsh.w<W){
183
+ long long old=llabs((long long)h[x0+tsh.w]-h[x0+tsh.w-1]);
184
+ long long nw=llabs((long long)h[x0+tsh.w]-nhbuf[tsh.w-1]);
185
+ dr+=nw-old;
186
+ }
187
+ long long gg=g; if(gg<l) gg=l;
188
+ bool take=false;
189
+ if(gg<bestg2) take=true;
190
+ else if(gg==bestg2){
191
+ if(dsum<bds2) take=true;
192
+ else if(dsum==bds2){
193
+ if(l<bl2) take=true;
194
+ else if(l==bl2){
195
+ if(dr<bdr2) take=true;
196
+ else if(dr==bdr2){
197
+ if(y0<by02) take=true;
198
+ else if(y0==by02){
199
+ if(x0<bx02) take=true;
200
+ else if(x0==bx02 && randtie && rng.coin()) take=true;
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
206
+ if(take){bestg2=gg;bti2=ti;bx2=x0;by2=y0;bl2=l;bds2=dsum;bdr2=dr;by02=y0;bx02=x0;}
207
+ }
208
+ }
209
+ if(bti2==-1) continue;
210
+ // Use waste = dsum - k for between-piece comparison (accounts for piece size)
211
+ long long waste2 = bds2 - p.k;
212
+ bool take=false;
213
+ if(bestg2<bestg) take=true;
214
+ else if(bestg2==bestg){
215
+ if(waste2<bds) take=true;
216
+ else if(waste2==bds){
217
+ if(bl2<bl) take=true;
218
+ else if(bl2==bl){
219
+ if(bdr2<bdr) take=true;
220
+ else if(bdr2==bdr){
221
+ if(by02<by0) take=true;
222
+ else if(by02==by0){
223
+ if(bx02<bx0) take=true;
224
+ else if(bx02==bx0 && randtie && rng.coin()) take=true;
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ if(take){bestg=bestg2;bti=bti2;bx=bx2;by=by2;bl=bl2;bds=waste2;bdr=bdr2;by0=by02;bx0=bx02;bestpos=pos;bestid=id;}
231
+ }
232
+ if(bti==-1){t++;stepCnt++;if(big&&stepCnt==5){auto now=chrono::steady_clock::now(); auto elapsed=chrono::duration<double,milli>(now-tStart).count(); auto batch=chrono::duration<double,milli>(now-batchStart).count(); double remT=max(0.0,TLms-elapsed); int remSteps=max(1,nm-t); double budget=remT*5.0/remSteps; if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1); batchStart=now; stepCnt=0;} continue;}
233
+ auto &tsh=ps[bestid].t[bti];
234
+ for(int j=0;j<tsh.w;j++){
235
+ int nh=h[bx+j];
236
+ if(tsh.hi[j]!=INT_MIN){
237
+ int cand=by+tsh.hi[j];
238
+ if(nh<cand) nh=cand;
239
+ }
240
+ h[bx+j]=nh;
241
+ }
242
+ if(g<bl) g=bl;
243
+ pl.push_back({bestid,bti,bx,by});
244
+ if(bestpos!=t) swap(o[t],o[bestpos]);
245
+ t++;
246
+ stepCnt++;
247
+ if(big&&stepCnt==5){
248
+ auto now=chrono::steady_clock::now();
249
+ auto elapsed=chrono::duration<double,milli>(now-tStart).count();
250
+ auto batch=chrono::duration<double,milli>(now-batchStart).count();
251
+ double remT=max(0.0,TLms-elapsed);
252
+ int remSteps=max(1,nm-t);
253
+ double budget=remT*5.0/remSteps;
254
+ if(batch<budget) dynLIM=min(maxBound,dynLIM+1); else dynLIM=max(1,dynLIM-1);
255
+ batchStart=now;
256
+ stepCnt=0;
257
+ }
258
+ }
259
+ int H=(int)g+1;
260
+ int maxX=-1;
261
+ for(auto &pp:pl){
262
+ auto &t=ps[pp.idx].t[pp.ti];
263
+ for(auto &q:t.c){int x=pp.x+q.first; if(x>maxX) maxX=x;}
264
+ }
265
+ int Wused=0;
266
+ if(maxX>=0){
267
+ vector<char> used(maxX+1,false);
268
+ for(auto &pp:pl){auto &t=ps[pp.idx].t[pp.ti]; for(auto &q:t.c){used[pp.x+q.first]=true;}}
269
+ for(int x=0;x<=maxX;x++) if(used[x]) Wused++;
270
+ }
271
+ int Wfinal=max(0,Wused);
272
+ long long A=1LL*H*max(1,Wfinal);
273
+ return R{A,max(1,Wfinal),H,move(pl)};
274
+ };
275
+ int minW=0; for(auto &p:ps) minW=max(minW,p.minW);
276
+
277
+ // Improved width estimation
278
+ double factor;
279
+ if (S < 1000) factor = 0.4;
280
+ else if (S < 3000) factor = 0.5;
281
+ else if (S < 10000) factor = 0.27;
282
+ else if (S < 30000) factor = 0.08;
283
+ else factor = 0.01;
284
+
285
+ int base = max(minW, (int)floor(sqrt((double)S * factor)));
286
+ vector<int> Ws;
287
+ {
288
+ unordered_set<int> used; used.reserve(512);
289
+ auto addW=[&](int w){if(w<minW) w=minW; if(used.insert(w).second) Ws.push_back(w);};
290
+ addW(base);
291
+ int span=min(96,max(20,base/2));
292
+ for(int d=1;d<=span;d++){addW(base-d); addW(base+d);}
293
+ addW(minW);
294
+ addW((int)max<long long>(minW,(S+base-1)/base));
295
+ for(int m=2;m<=6;m++){addW(base*m/3); addW((int)max<long long>(minW,S/((base*m/3)?(base*m/3):1)));}
296
+ // Add sqrt(S) based widths for more square-like rectangles
297
+ int sqrtS = max(minW, (int)floor(sqrt((double)S)));
298
+ addW(sqrtS);
299
+ addW(sqrtS+1);
300
+ addW(sqrtS-1);
301
+ addW(sqrtS*2/3);
302
+ addW(sqrtS/2);
303
+ sort(Ws.begin(),Ws.end(),[&](int a,int b){int da=abs(a-base),db=abs(b-base); if(da!=db) return da<db; return a<b;});
304
+ }
305
+ long long bestA=LLONG_MAX; int bestW=0,bestH=0; R bestR; bool hasBestmine=false;
306
+ auto t0=chrono::steady_clock::now();
307
+ const double TL=1980.0;
308
+ double avg=250.0; int cnt=0;
309
+
310
+ // Prepare multiple orderings
311
+ vector<vector<int>> base_orders;
312
+ base_orders.push_back(ord_asc_mindim());
313
+ base_orders.push_back(ord_desc_area());
314
+ base_orders.push_back(ord_desc_maxdim());
315
+ base_orders.push_back(ord_desc_bbox());
316
+ base_orders.push_back(ord_flexibility());
317
+
318
+ // Track best ordering index per width for perturbation
319
+ int bestOrderIdx = 0;
320
+
321
+ for(int wi=0;wi<(int)Ws.size();wi++){
322
+ auto now=chrono::steady_clock::now();
323
+ double used_time=chrono::duration<double,milli>(now-t0).count();
324
+ if(used_time+avg*1.3>TL) break;
325
+ int W=Ws[wi];
326
+
327
+ // Try each base ordering
328
+ for(int oi=0;oi<(int)base_orders.size();oi++){
329
+ now=chrono::steady_clock::now();
330
+ double used2=chrono::duration<double,milli>(now-t0).count();
331
+ if(used2+avg*1.15>TL) break;
332
+ bool randtie=(oi>=1);
333
+ auto t1=chrono::steady_clock::now();
334
+ R r=pack(W,base_orders[oi],rng,randtie);
335
+ auto t2=chrono::steady_clock::now();
336
+ double dt=chrono::duration<double,milli>(t2-t1).count();
337
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
338
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
339
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
340
+ bestOrderIdx=oi;
341
+ }
342
+ }
343
+
344
+ // Perturbation of best ordering + random orderings
345
+ int nswaps = max(1, n/20);
346
+ for(int ri=0;ri<4;ri++){
347
+ now=chrono::steady_clock::now();
348
+ double used2=chrono::duration<double,milli>(now-t0).count();
349
+ if(used2+avg*1.15>TL) break;
350
+ auto t1=chrono::steady_clock::now();
351
+ vector<int> order;
352
+ if(ri < 2) order = ord_perturb(base_orders[bestOrderIdx], nswaps);
353
+ else order = ord_random();
354
+ R r=pack(W,order,rng,true);
355
+ auto t2=chrono::steady_clock::now();
356
+ double dt=chrono::duration<double,milli>(t2-t1).count();
357
+ cnt++; avg=(avg*(cnt-1)+dt)/cnt;
358
+ if(!hasBestmine || r.A<bestA || (r.A==bestA && (r.H<bestH || (r.H==bestH && r.W<bestW)))){
359
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
360
+ }
361
+ }
362
+ }
363
+ if(!hasBestmine){
364
+ int W=max(minW,(int)floor(sqrt((double)S)));
365
+ auto o=ord_asc_mindim();
366
+ R r=pack(W,o,rng,false);
367
+ bestA=r.A; bestW=r.W; bestH=r.H; bestR=r; hasBestmine=true;
368
+ }
369
+ int maxX=-1;
370
+ for(auto &p:bestR.pl){
371
+ auto &t=ps[p.idx].t[p.ti];
372
+ for(auto &q:t.c){int x=p.x+q.first; if(x>maxX) maxX=x;}
373
+ }
374
+ vector<int> mapx(maxX+1,-1);
375
+ if(maxX>=0){
376
+ vector<char> used(maxX+1,false);
377
+ for(auto &p:bestR.pl){
378
+ auto &t=ps[p.idx].t[p.ti];
379
+ for(auto &q:t.c){used[p.x+q.first]=true;}
380
+ }
381
+ int cur=0;
382
+ for(int x=0;x<=maxX;x++) if(used[x]) mapx[x]=cur++;
383
+ }
384
+ vector<array<int,4>> ans(n,{0,0,0,0});
385
+ for(auto &p:bestR.pl){
386
+ auto &t=ps[p.idx].t[p.ti];
387
+ int bx = (mapx.empty()?p.x:mapx[p.x]);
388
+ int Xi = bx - t.minx;
389
+ int Yi = p.y - t.miny;
390
+ int Ri = (4 - (t.r%4) + 4) % 4;
391
+ int Fi = t.f;
392
+ ans[p.idx]={Xi,Yi,Ri,Fi};
393
+ }
394
+ cout<<bestR.W<<" "<<bestR.H<<"\n";
395
+ for(int i=0;i<n;i++){
396
+ cout<<ans[i][0]<<" "<<ans[i][1]<<" "<<ans[i][2]<<" "<<ans[i][3]<<"\n";
397
+ }
398
+ return 0;
399
+ }
docker_space/frontier_cs_1/examples/deepseekreasoner.cpp ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <string>
3
+ #include <vector>
4
+ #include <algorithm>
5
+ #include <random>
6
+ #include <cctype>
7
+ #include <cmath>
8
+
9
+ using namespace std;
10
+
11
+ const long long M = 20000000; // mg
12
+ const long long L = 25000000; // µL
13
+
14
+ struct Treasure {
15
+ string name;
16
+ long long q; // max quantity
17
+ long long v; // value per item
18
+ long long m; // mass per item (mg)
19
+ long long l; // volume per item (µL)
20
+ double density;
21
+ };
22
+
23
+ vector<Treasure> treasures;
24
+
25
+ void parseInput() {
26
+ string s;
27
+ char c;
28
+ while (cin.get(c)) s += c;
29
+
30
+ size_t i = 0;
31
+ auto skipWS = [&]() {
32
+ while (i < s.size() && isspace(s[i])) i++;
33
+ };
34
+
35
+ skipWS();
36
+ if (s[i] != '{') return;
37
+ i++;
38
+ while (true) {
39
+ skipWS();
40
+ if (s[i] == '}') break;
41
+ if (s[i] == '"') {
42
+ i++;
43
+ size_t start = i;
44
+ while (s[i] != '"') i++;
45
+ string key = s.substr(start, i - start);
46
+ i++; // skip '"'
47
+ skipWS();
48
+ if (s[i] != ':') return;
49
+ i++;
50
+ skipWS();
51
+ if (s[i] != '[') return;
52
+ i++;
53
+ vector<long long> nums;
54
+ for (int j = 0; j < 4; j++) {
55
+ skipWS();
56
+ long long num = 0;
57
+ while (i < s.size() && isdigit(s[i])) {
58
+ num = num * 10 + (s[i] - '0');
59
+ i++;
60
+ }
61
+ nums.push_back(num);
62
+ if (j < 3) {
63
+ skipWS();
64
+ if (s[i] != ',') return;
65
+ i++;
66
+ }
67
+ }
68
+ skipWS();
69
+ if (s[i] != ']') return;
70
+ i++;
71
+ treasures.push_back({key, nums[0], nums[1], nums[2], nums[3], 0.0});
72
+ skipWS();
73
+ if (s[i] == ',') i++;
74
+ else if (s[i] == '}') break;
75
+ else return;
76
+ }
77
+ }
78
+ }
79
+
80
+ vector<long long> greedy(const vector<int>& order) {
81
+ vector<long long> cnt(treasures.size(), 0);
82
+ long long cur_m = 0, cur_l = 0;
83
+ for (int idx : order) {
84
+ const Treasure& t = treasures[idx];
85
+ long long maxTake = t.q;
86
+ if (t.m > 0) maxTake = min(maxTake, (M - cur_m) / t.m);
87
+ if (t.l > 0) maxTake = min(maxTake, (L - cur_l) / t.l);
88
+ cnt[idx] = maxTake;
89
+ cur_m += maxTake * t.m;
90
+ cur_l += maxTake * t.l;
91
+ }
92
+ return cnt;
93
+ }
94
+
95
+ void improve(vector<long long>& cnt, long long& cur_m, long long& cur_l, long long& cur_v) {
96
+ bool improved = true;
97
+ while (improved) {
98
+ improved = false;
99
+ // try to add one item
100
+ for (int i = 0; i < (int)treasures.size(); i++) {
101
+ if (cnt[i] < treasures[i].q) {
102
+ long long new_m = cur_m + treasures[i].m;
103
+ long long new_l = cur_l + treasures[i].l;
104
+ if (new_m <= M && new_l <= L) {
105
+ cnt[i]++;
106
+ cur_m = new_m;
107
+ cur_l = new_l;
108
+ cur_v += treasures[i].v;
109
+ improved = true;
110
+ }
111
+ }
112
+ }
113
+ // try to swap: remove one from j, add one to i
114
+ for (int i = 0; i < (int)treasures.size() && !improved; i++) {
115
+ for (int j = 0; j < (int)treasures.size(); j++) {
116
+ if (i == j) continue;
117
+ if (cnt[i] < treasures[i].q && cnt[j] > 0) {
118
+ long long delta_m = treasures[i].m - treasures[j].m;
119
+ long long delta_l = treasures[i].l - treasures[j].l;
120
+ long long delta_v = treasures[i].v - treasures[j].v;
121
+ if (delta_v > 0 && cur_m + delta_m <= M && cur_l + delta_l <= L) {
122
+ cnt[i]++; cnt[j]--;
123
+ cur_m += delta_m;
124
+ cur_l += delta_l;
125
+ cur_v += delta_v;
126
+ improved = true;
127
+ break;
128
+ }
129
+ }
130
+ }
131
+ if (improved) break;
132
+ }
133
+ }
134
+ }
135
+
136
+ void finalRefine(vector<long long>& cnt, long long& cur_m, long long& cur_l, long long& cur_v) {
137
+ int n = treasures.size();
138
+ for (int i = 0; i < n; i++) {
139
+ for (int j = i+1; j < n; j++) {
140
+ long long cur_xi = cnt[i], cur_xj = cnt[j];
141
+ long long base_m = cur_m - cur_xi*treasures[i].m - cur_xj*treasures[j].m;
142
+ long long base_l = cur_l - cur_xi*treasures[i].l - cur_xj*treasures[j].l;
143
+ long long base_v = cur_v - cur_xi*treasures[i].v - cur_xj*treasures[j].v;
144
+ long long best_xi = cur_xi, best_xj = cur_xj;
145
+ long long best_m = cur_m, best_l = cur_l, best_v = cur_v;
146
+ for (long long xi = max(0LL, cur_xi-10); xi <= min(treasures[i].q, cur_xi+10); xi++) {
147
+ for (long long xj = max(0LL, cur_xj-10); xj <= min(treasures[j].q, cur_xj+10); xj++) {
148
+ long long new_m = base_m + xi*treasures[i].m + xj*treasures[j].m;
149
+ long long new_l = base_l + xi*treasures[i].l + xj*treasures[j].l;
150
+ if (new_m <= M && new_l <= L) {
151
+ long long new_v = base_v + xi*treasures[i].v + xj*treasures[j].v;
152
+ if (new_v > best_v) {
153
+ best_v = new_v;
154
+ best_m = new_m;
155
+ best_l = new_l;
156
+ best_xi = xi;
157
+ best_xj = xj;
158
+ }
159
+ }
160
+ }
161
+ }
162
+ if (best_xi != cur_xi || best_xj != cur_xj) {
163
+ cnt[i] = best_xi;
164
+ cnt[j] = best_xj;
165
+ cur_m = best_m;
166
+ cur_l = best_l;
167
+ cur_v = best_v;
168
+ }
169
+ }
170
+ }
171
+ }
172
+
173
+ int main() {
174
+ parseInput();
175
+ int n = treasures.size();
176
+ // compute density: value per combined resource
177
+ for (int i = 0; i < n; i++) {
178
+ // density = v_i / (m_i/M + l_i/L) = v_i * M * L / (m_i * L + l_i * M)
179
+ double denom = treasures[i].m * L + treasures[i].l * M;
180
+ treasures[i].density = (denom > 0) ? (treasures[i].v * M * L / denom) : 1e18;
181
+ }
182
+
183
+ vector<int> order(n);
184
+ for (int i = 0; i < n; i++) order[i] = i;
185
+ sort(order.begin(), order.end(), [&](int a, int b) {
186
+ return treasures[a].density > treasures[b].density;
187
+ });
188
+
189
+ // initial solution from density order
190
+ vector<long long> best_cnt = greedy(order);
191
+ long long best_m = 0, best_l = 0, best_v = 0;
192
+ for (int i = 0; i < n; i++) {
193
+ best_m += best_cnt[i] * treasures[i].m;
194
+ best_l += best_cnt[i] * treasures[i].l;
195
+ best_v += best_cnt[i] * treasures[i].v;
196
+ }
197
+ improve(best_cnt, best_m, best_l, best_v);
198
+
199
+ // random permutations
200
+ mt19937 rng(123456); // fixed seed for reproducibility
201
+ for (int iter = 0; iter < 100; iter++) {
202
+ shuffle(order.begin(), order.end(), rng);
203
+ vector<long long> cnt = greedy(order);
204
+ long long cur_m = 0, cur_l = 0, cur_v = 0;
205
+ for (int i = 0; i < n; i++) {
206
+ cur_m += cnt[i] * treasures[i].m;
207
+ cur_l += cnt[i] * treasures[i].l;
208
+ cur_v += cnt[i] * treasures[i].v;
209
+ }
210
+ improve(cnt, cur_m, cur_l, cur_v);
211
+ if (cur_v > best_v) {
212
+ best_v = cur_v;
213
+ best_m = cur_m;
214
+ best_l = cur_l;
215
+ best_cnt = cnt;
216
+ }
217
+ }
218
+
219
+ // final refinement on pairs
220
+ finalRefine(best_cnt, best_m, best_l, best_v);
221
+
222
+ // output JSON
223
+ cout << "{\n";
224
+ for (int i = 0; i < n; i++) {
225
+ cout << " \"" << treasures[i].name << "\": " << best_cnt[i];
226
+ if (i != n-1) cout << ",";
227
+ cout << "\n";
228
+ }
229
+ cout << "}\n";
230
+
231
+ return 0;
232
+ }
docker_space/frontier_cs_1/examples/deepseekreasoner_1.cpp ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <string>
3
+ #include <vector>
4
+ #include <unordered_map>
5
+ #include <algorithm>
6
+
7
+ using namespace std;
8
+
9
+ const long long M_MAX = 20000000; // 20 kg in mg
10
+ const long long V_MAX = 25000000; // 25 liters in µL
11
+
12
+ struct BinaryItem {
13
+ long long mass;
14
+ long long volume;
15
+ long long value;
16
+ int category;
17
+ int copies;
18
+ };
19
+
20
+ struct State {
21
+ long long volume;
22
+ long long value;
23
+ int prev_item; // index in binary_items
24
+ long long prev_mass;
25
+ };
26
+
27
+ int main() {
28
+ // Read the whole input
29
+ string input;
30
+ char c;
31
+ while (cin.get(c)) input += c;
32
+
33
+ // Parse JSON
34
+ vector<string> categories;
35
+ vector<long long> q, v, m, l;
36
+ size_t pos = 0;
37
+ while (pos < input.size() && input[pos] != '{') ++pos;
38
+ ++pos; // skip '{'
39
+ for (int i = 0; i < 12; ++i) {
40
+ // Key
41
+ while (pos < input.size() && input[pos] != '"') ++pos;
42
+ size_t start_key = pos + 1;
43
+ ++pos;
44
+ while (pos < input.size() && input[pos] != '"') ++pos;
45
+ string key = input.substr(start_key, pos - start_key);
46
+ categories.push_back(key);
47
+ ++pos; // skip '"'
48
+
49
+ // Skip to '['
50
+ while (pos < input.size() && input[pos] != '[') ++pos;
51
+ ++pos;
52
+
53
+ // Four integers
54
+ long long nums[4];
55
+ for (int j = 0; j < 4; ++j) {
56
+ while (pos < input.size() && (input[pos] < '0' || input[pos] > '9')) ++pos;
57
+ size_t start_num = pos;
58
+ while (pos < input.size() && input[pos] >= '0' && input[pos] <= '9') ++pos;
59
+ nums[j] = stoll(input.substr(start_num, pos - start_num));
60
+ if (j < 3) {
61
+ while (pos < input.size() && input[pos] != ',') ++pos;
62
+ ++pos;
63
+ }
64
+ }
65
+ q.push_back(nums[0]);
66
+ v.push_back(nums[1]);
67
+ m.push_back(nums[2]);
68
+ l.push_back(nums[3]);
69
+
70
+ // Skip ']'
71
+ while (pos < input.size() && input[pos] != ']') ++pos;
72
+ ++pos;
73
+ // Skip whitespace and comma (or '}')
74
+ while (pos < input.size() && (input[pos] == ' ' || input[pos] == '\n' || input[pos] == '\r' || input[pos] == '\t'))
75
+ ++pos;
76
+ if (i < 11 && input[pos] == ',') ++pos;
77
+ }
78
+
79
+ // Build binary items (bounded knapsack -> 0/1 via powers of two)
80
+ vector<BinaryItem> binary_items;
81
+ int cat_count = categories.size();
82
+ for (int i = 0; i < cat_count; ++i) {
83
+ long long quantity = q[i];
84
+ int mult = 1;
85
+ while (quantity > 0) {
86
+ long long take = min((long long)mult, quantity);
87
+ binary_items.push_back({
88
+ take * m[i],
89
+ take * l[i],
90
+ take * v[i],
91
+ i,
92
+ (int)take
93
+ });
94
+ quantity -= take;
95
+ mult <<= 1;
96
+ }
97
+ }
98
+
99
+ // Sparse DP: map mass -> best state (volume, value, back pointer)
100
+ unordered_map<long long, State> dp;
101
+ dp[0] = {0, 0, -1, -1};
102
+ long long best_value = 0;
103
+ long long best_mass = 0;
104
+
105
+ int item_count = binary_items.size();
106
+ for (int idx = 0; idx < item_count; ++idx) {
107
+ const BinaryItem& it = binary_items[idx];
108
+ unordered_map<long long, State> updates;
109
+
110
+ for (const auto& entry : dp) {
111
+ long long old_mass = entry.first;
112
+ const State& s = entry.second;
113
+
114
+ long long new_mass = old_mass + it.mass;
115
+ if (new_mass > M_MAX) continue;
116
+ long long new_volume = s.volume + it.volume;
117
+ if (new_volume > V_MAX) continue;
118
+ long long new_value = s.value + it.value;
119
+
120
+ bool better = false;
121
+ auto cur_it = dp.find(new_mass);
122
+ if (cur_it == dp.end()) {
123
+ better = true;
124
+ } else {
125
+ const State& cur = cur_it->second;
126
+ if (new_value > cur.value ||
127
+ (new_value == cur.value && new_volume < cur.volume))
128
+ better = true;
129
+ }
130
+
131
+ if (better) {
132
+ auto upd_it = updates.find(new_mass);
133
+ if (upd_it == updates.end() ||
134
+ new_value > upd_it->second.value ||
135
+ (new_value == upd_it->second.value && new_volume < upd_it->second.volume))
136
+ {
137
+ updates[new_mass] = {new_volume, new_value, idx, old_mass};
138
+ }
139
+ }
140
+ }
141
+
142
+ // Merge updates into dp
143
+ for (const auto& p : updates) {
144
+ dp[p.first] = p.second;
145
+ if (p.second.value > best_value) {
146
+ best_value = p.second.value;
147
+ best_mass = p.first;
148
+ }
149
+ }
150
+ }
151
+
152
+ // Reconstruct counts
153
+ vector<long long> counts(cat_count, 0);
154
+ long long cur_mass = best_mass;
155
+ while (cur_mass > 0) {
156
+ State& s = dp[cur_mass];
157
+ int idx = s.prev_item;
158
+ if (idx == -1) break;
159
+ BinaryItem& it = binary_items[idx];
160
+ counts[it.category] += it.copies;
161
+ cur_mass = s.prev_mass;
162
+ }
163
+
164
+ // Output JSON
165
+ cout << "{\n";
166
+ for (int i = 0; i < cat_count; ++i) {
167
+ cout << " \"" << categories[i] << "\": " << counts[i];
168
+ if (i < cat_count - 1) cout << ",";
169
+ cout << "\n";
170
+ }
171
+ cout << "}" << endl;
172
+
173
+ return 0;
174
+ }
docker_space/frontier_cs_1/examples/deepseekreasoner_2.cpp ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <vector>
3
+ #include <string>
4
+ #include <algorithm>
5
+ #include <numeric>
6
+ #include <cctype>
7
+ #include <cmath>
8
+
9
+ using namespace std;
10
+
11
+ struct Item {
12
+ string name;
13
+ int q, v, m, l;
14
+ };
15
+
16
+ const long long Mmax = 20000000;
17
+ const long long Vmax = 25000000;
18
+
19
+ vector<Item> items;
20
+ vector<int> best_counts(12, 0);
21
+ long long best_value = 0;
22
+
23
+ void update_best(const vector<int>& counts) {
24
+ long long value = 0;
25
+ for (int i = 0; i < 12; ++i) {
26
+ value += counts[i] * (long long)items[i].v;
27
+ }
28
+ if (value > best_value) {
29
+ best_value = value;
30
+ best_counts = counts;
31
+ }
32
+ }
33
+
34
+ vector<int> greedy_fill(const vector<int>& order) {
35
+ vector<int> counts(12, 0);
36
+ long long cur_mass = 0, cur_vol = 0;
37
+ for (int idx : order) {
38
+ const Item& it = items[idx];
39
+ int maxTake = min(it.q, (int)((Mmax - cur_mass) / it.m), (int)((Vmax - cur_vol) / it.l));
40
+ if (maxTake > 0) {
41
+ counts[idx] = maxTake;
42
+ cur_mass += maxTake * (long long)it.m;
43
+ cur_vol += maxTake * (long long)it.l;
44
+ }
45
+ }
46
+ return counts;
47
+ }
48
+
49
+ void swap_local_search(vector<int>& counts, long long& cur_mass, long long& cur_vol) {
50
+ bool improved = true;
51
+ while (improved) {
52
+ improved = false;
53
+ for (int i = 0; i < 12 && !improved; ++i) {
54
+ if (counts[i] >= items[i].q) continue;
55
+ const Item& it_i = items[i];
56
+ // 1-for-1 swap
57
+ for (int j = 0; j < 12 && !improved; ++j) {
58
+ if (counts[j] == 0) continue;
59
+ const Item& it_j = items[j];
60
+ if (cur_mass - it_j.m + it_i.m <= Mmax && cur_vol - it_j.l + it_i.l <= Vmax) {
61
+ if (it_i.v > it_j.v) {
62
+ counts[i]++; counts[j]--;
63
+ cur_mass += it_i.m - it_j.m;
64
+ cur_vol += it_i.l - it_j.l;
65
+ improved = true;
66
+ }
67
+ }
68
+ }
69
+ if (improved) break;
70
+ // 1-for-2 swap
71
+ for (int j = 0; j < 12 && !improved; ++j) {
72
+ if (counts[j] == 0) continue;
73
+ const Item& it_j = items[j];
74
+ for (int k = 0; k < 12 && !improved; ++k) {
75
+ if (counts[k] == 0) continue;
76
+ if (k == j && counts[j] < 2) continue;
77
+ const Item& it_k = items[k];
78
+ if (cur_mass - it_j.m - it_k.m + it_i.m <= Mmax &&
79
+ cur_vol - it_j.l - it_k.l + it_i.l <= Vmax) {
80
+ long long removed = it_j.v + (k == j ? it_j.v : it_k.v);
81
+ if (it_i.v > removed) {
82
+ counts[i]++; counts[j]--;
83
+ if (k == j) counts[j]--;
84
+ else counts[k]--;
85
+ cur_mass += it_i.m - it_j.m - it_k.m;
86
+ cur_vol += it_i.l - it_j.l - it_k.l;
87
+ improved = true;
88
+ }
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ }
95
+
96
+ void removal_reopt(const vector<int>& order, const vector<int>& base_counts,
97
+ long long base_mass, long long base_vol) {
98
+ // subsets of size 1,2,3
99
+ for (int sz = 1; sz <= 3; ++sz) {
100
+ if (sz == 1) {
101
+ for (int i = 0; i < 12; ++i) {
102
+ vector<int> counts = base_counts;
103
+ long long cur_mass = base_mass;
104
+ long long cur_vol = base_vol;
105
+ if (counts[i] > 0) {
106
+ cur_mass -= counts[i] * (long long)items[i].m;
107
+ cur_vol -= counts[i] * (long long)items[i].l;
108
+ counts[i] = 0;
109
+ }
110
+ for (int idx : order) {
111
+ if (idx == i) continue;
112
+ const Item& it = items[idx];
113
+ int maxTake = min(it.q - counts[idx],
114
+ (int)((Mmax - cur_mass) / it.m),
115
+ (int)((Vmax - cur_vol) / it.l));
116
+ if (maxTake > 0) {
117
+ counts[idx] += maxTake;
118
+ cur_mass += maxTake * (long long)it.m;
119
+ cur_vol += maxTake * (long long)it.l;
120
+ }
121
+ }
122
+ update_best(counts);
123
+ }
124
+ } else if (sz == 2) {
125
+ for (int i = 0; i < 12; ++i) {
126
+ for (int j = i+1; j < 12; ++j) {
127
+ vector<int> counts = base_counts;
128
+ long long cur_mass = base_mass;
129
+ long long cur_vol = base_vol;
130
+ for (int t : {i, j}) {
131
+ if (counts[t] > 0) {
132
+ cur_mass -= counts[t] * (long long)items[t].m;
133
+ cur_vol -= counts[t] * (long long)items[t].l;
134
+ counts[t] = 0;
135
+ }
136
+ }
137
+ for (int idx : order) {
138
+ if (idx == i || idx == j) continue;
139
+ const Item& it = items[idx];
140
+ int maxTake = min(it.q - counts[idx],
141
+ (int)((Mmax - cur_mass) / it.m),
142
+ (int)((Vmax - cur_vol) / it.l));
143
+ if (maxTake > 0) {
144
+ counts[idx] += maxTake;
145
+ cur_mass += maxTake * (long long)it.m;
146
+ cur_vol += maxTake * (long long)it.l;
147
+ }
148
+ }
149
+ update_best(counts);
150
+ }
151
+ }
152
+ } else { // sz == 3
153
+ for (int i = 0; i < 12; ++i) {
154
+ for (int j = i+1; j < 12; ++j) {
155
+ for (int k = j+1; k < 12; ++k) {
156
+ vector<int> counts = base_counts;
157
+ long long cur_mass = base_mass;
158
+ long long cur_vol = base_vol;
159
+ for (int t : {i, j, k}) {
160
+ if (counts[t] > 0) {
161
+ cur_mass -= counts[t] * (long long)items[t].m;
162
+ cur_vol -= counts[t] * (long long)items[t].l;
163
+ counts[t] = 0;
164
+ }
165
+ }
166
+ for (int idx : order) {
167
+ if (idx == i || idx == j || idx == k) continue;
168
+ const Item& it = items[idx];
169
+ int maxTake = min(it.q - counts[idx],
170
+ (int)((Mmax - cur_mass) / it.m),
171
+ (int)((Vmax - cur_vol) / it.l));
172
+ if (maxTake > 0) {
173
+ counts[idx] += maxTake;
174
+ cur_mass += maxTake * (long long)it.m;
175
+ cur_vol += maxTake * (long long)it.l;
176
+ }
177
+ }
178
+ update_best(counts);
179
+ }
180
+ }
181
+ }
182
+ }
183
+ }
184
+ }
185
+
186
+ int main() {
187
+ // Read entire input
188
+ string s, line;
189
+ while (getline(cin, line)) s += line;
190
+ // Remove whitespace
191
+ s.erase(remove_if(s.begin(), s.end(), ::isspace), s.end());
192
+ // Parse JSON
193
+ // Remove outer braces
194
+ if (s.front() == '{') s = s.substr(1, s.size()-2);
195
+ size_t pos = 0;
196
+ while (pos < s.size()) {
197
+ if (s[pos] != '"') break;
198
+ size_t key_start = pos+1;
199
+ size_t key_end = s.find('"', key_start);
200
+ string key = s.substr(key_start, key_end - key_start);
201
+ pos = key_end + 1;
202
+ if (s[pos] != ':') break;
203
+ pos++;
204
+ if (s[pos] != '[') break;
205
+ pos++;
206
+ size_t array_end = s.find(']', pos);
207
+ string array_str = s.substr(pos, array_end - pos);
208
+ vector<int> nums;
209
+ size_t comma = 0;
210
+ while (true) {
211
+ size_t next_comma = array_str.find(',', comma);
212
+ if (next_comma == string::npos) {
213
+ nums.push_back(stoi(array_str.substr(comma)));
214
+ break;
215
+ }
216
+ nums.push_back(stoi(array_str.substr(comma, next_comma - comma)));
217
+ comma = next_comma + 1;
218
+ }
219
+ items.push_back({key, nums[0], nums[1], nums[2], nums[3]});
220
+ pos = array_end + 1;
221
+ if (pos < s.size() && s[pos] == ',') pos++;
222
+ }
223
+
224
+ // Three metrics
225
+ for (int metric = 1; metric <= 3; ++metric) {
226
+ vector<int> order(12);
227
+ iota(order.begin(), order.end(), 0);
228
+ if (metric == 1) {
229
+ sort(order.begin(), order.end(), [](int a, int b) {
230
+ double da = items[a].v / (items[a].m / (double)Mmax + items[a].l / (double)Vmax);
231
+ double db = items[b].v / (items[b].m / (double)Mmax + items[b].l / (double)Vmax);
232
+ return da > db;
233
+ });
234
+ } else if (metric == 2) {
235
+ sort(order.begin(), order.end(), [](int a, int b) {
236
+ return (long long)items[a].v * items[b].m > (long long)items[b].v * items[a].m;
237
+ });
238
+ } else {
239
+ sort(order.begin(), order.end(), [](int a, int b) {
240
+ return (long long)items[a].v * items[b].l > (long long)items[b].v * items[a].l;
241
+ });
242
+ }
243
+
244
+ vector<int> counts = greedy_fill(order);
245
+ long long cur_mass = 0, cur_vol = 0;
246
+ for (int i = 0; i < 12; ++i) {
247
+ cur_mass += counts[i] * (long long)items[i].m;
248
+ cur_vol += counts[i] * (long long)items[i].l;
249
+ }
250
+ swap_local_search(counts, cur_mass, cur_vol);
251
+ update_best(counts);
252
+ removal_reopt(order, counts, cur_mass, cur_vol);
253
+ }
254
+
255
+ // Output JSON
256
+ cout << "{\n";
257
+ for (int i = 0; i < 12; ++i) {
258
+ cout << " \"" << items[i].name << "\": " << best_counts[i];
259
+ if (i != 11) cout << ",";
260
+ cout << "\n";
261
+ }
262
+ cout << "}" << endl;
263
+
264
+ return 0;
265
+ }
docker_space/frontier_cs_1/examples/deepseekreasoner_3.cpp ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <vector>
3
+ #include <string>
4
+ #include <algorithm>
5
+ #include <cmath>
6
+ #include <cctype>
7
+ #include <sstream>
8
+ #include <map>
9
+
10
+ using namespace std;
11
+
12
+ typedef long long ll;
13
+
14
+ struct Item {
15
+ string name;
16
+ ll q, v, m, l;
17
+ ll cnt; // number taken
18
+ };
19
+
20
+ // Simple JSON parser for this specific format
21
+ bool parse_input(const string& json, vector<Item>& items, vector<string>& order) {
22
+ items.clear();
23
+ order.clear();
24
+ size_t i = 0;
25
+ // skip whitespace
26
+ while (i < json.size() && isspace(json[i])) i++;
27
+ if (i >= json.size() || json[i] != '{') return false;
28
+ i++;
29
+ while (i < json.size()) {
30
+ // skip whitespace
31
+ while (i < json.size() && isspace(json[i])) i++;
32
+ if (i >= json.size()) return false;
33
+ if (json[i] == '}') break;
34
+ // parse key
35
+ if (json[i] != '"') return false;
36
+ i++;
37
+ string key;
38
+ while (i < json.size() && json[i] != '"') key += json[i++];
39
+ if (i >= json.size() || json[i] != '"') return false;
40
+ i++; // skip closing quote
41
+ // skip to ':'
42
+ while (i < json.size() && isspace(json[i])) i++;
43
+ if (i >= json.size() || json[i] != ':') return false;
44
+ i++;
45
+ // skip whitespace
46
+ while (i < json.size() && isspace(json[i])) i++;
47
+ // expect '['
48
+ if (i >= json.size() || json[i] != '[') return false;
49
+ i++;
50
+ // parse four integers
51
+ vector<ll> nums;
52
+ while (nums.size() < 4) {
53
+ while (i < json.size() && isspace(json[i])) i++;
54
+ if (i >= json.size()) return false;
55
+ ll val = 0;
56
+ bool neg = false;
57
+ if (json[i] == '-') { neg = true; i++; }
58
+ while (i < json.size() && isdigit(json[i])) {
59
+ val = val * 10 + (json[i] - '0');
60
+ i++;
61
+ }
62
+ if (neg) val = -val;
63
+ nums.push_back(val);
64
+ while (i < json.size() && isspace(json[i])) i++;
65
+ if (nums.size() < 4) {
66
+ if (i >= json.size() || json[i] != ',') return false;
67
+ i++;
68
+ }
69
+ }
70
+ // expect ']'
71
+ while (i < json.size() && isspace(json[i])) i++;
72
+ if (i >= json.size() || json[i] != ']') return false;
73
+ i++;
74
+ // skip to ',' or '}'
75
+ while (i < json.size() && isspace(json[i])) i++;
76
+ if (i < json.size() && json[i] == ',') i++;
77
+ // store item
78
+ items.push_back({key, nums[0], nums[1], nums[2], nums[3], 0});
79
+ order.push_back(key);
80
+ }
81
+ return true;
82
+ }
83
+
84
+ int main() {
85
+ // read entire input
86
+ string json;
87
+ char ch;
88
+ while (cin.get(ch)) json += ch;
89
+
90
+ vector<Item> items;
91
+ vector<string> order;
92
+ if (!parse_input(json, items, order)) {
93
+ // should not happen with valid input
94
+ return 1;
95
+ }
96
+
97
+ const ll M_MAX = 20000000; // mg
98
+ const ll V_MAX = 25000000; // µL
99
+ ll remaining_mass = M_MAX;
100
+ ll remaining_volume = V_MAX;
101
+ int n = items.size(); // should be 12
102
+
103
+ // Greedy: one at a time, choose item with highest score based on remaining capacities
104
+ while (true) {
105
+ double best_score = -1;
106
+ int best_idx = -1;
107
+ for (int i = 0; i < n; i++) {
108
+ if (items[i].cnt >= items[i].q) continue;
109
+ if (items[i].m > remaining_mass || items[i].l > remaining_volume) continue;
110
+ // score = value per unit of normalized resource consumption
111
+ double score = items[i].v / (items[i].m / (double)remaining_mass + items[i].l / (double)remaining_volume);
112
+ if (score > best_score) {
113
+ best_score = score;
114
+ best_idx = i;
115
+ }
116
+ }
117
+ if (best_idx == -1) break;
118
+ // take one
119
+ items[best_idx].cnt++;
120
+ remaining_mass -= items[best_idx].m;
121
+ remaining_volume -= items[best_idx].l;
122
+ }
123
+
124
+ // Local improvement: try swaps and additions
125
+ bool improved = true;
126
+ while (improved) {
127
+ improved = false;
128
+ // Try to add an item without removing
129
+ for (int j = 0; j < n; j++) {
130
+ if (items[j].cnt >= items[j].q) continue;
131
+ if (items[j].m <= remaining_mass && items[j].l <= remaining_volume) {
132
+ items[j].cnt++;
133
+ remaining_mass -= items[j].m;
134
+ remaining_volume -= items[j].l;
135
+ improved = true;
136
+ break;
137
+ }
138
+ }
139
+ if (improved) continue;
140
+ // Try to swap one item for another (remove one i, add one j)
141
+ for (int i = 0; i < n; i++) {
142
+ if (items[i].cnt == 0) continue;
143
+ for (int j = 0; j < n; j++) {
144
+ if (i == j) continue;
145
+ if (items[j].cnt >= items[j].q) continue;
146
+ // Check if swapping increases value and is feasible
147
+ if (items[j].v > items[i].v &&
148
+ remaining_mass + items[i].m >= items[j].m &&
149
+ remaining_volume + items[i].l >= items[j].l) {
150
+ // Perform swap
151
+ items[i].cnt--;
152
+ items[j].cnt++;
153
+ remaining_mass += items[i].m - items[j].m;
154
+ remaining_volume += items[i].l - items[j].l;
155
+ improved = true;
156
+ break;
157
+ }
158
+ }
159
+ if (improved) break;
160
+ }
161
+ }
162
+
163
+ // Output JSON in the original key order
164
+ cout << "{";
165
+ for (size_t idx = 0; idx < order.size(); idx++) {
166
+ string key = order[idx];
167
+ // find item with that name
168
+ for (const auto& it : items) {
169
+ if (it.name == key) {
170
+ cout << "\"" << key << "\": " << it.cnt;
171
+ break;
172
+ }
173
+ }
174
+ if (idx != order.size() - 1) cout << ",";
175
+ }
176
+ cout << "}" << endl;
177
+
178
+ return 0;
179
+ }
docker_space/frontier_cs_1/examples/deepseekreasoner_4.cpp ADDED
@@ -0,0 +1,300 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <string>
3
+ #include <vector>
4
+ #include <algorithm>
5
+ #include <cmath>
6
+ #include <cctype>
7
+ #include <sstream>
8
+ #include <cstring>
9
+
10
+ using namespace std;
11
+
12
+ typedef long long ll;
13
+
14
+ const ll M = 20000000; // mass limit in mg
15
+ const ll L = 25000000; // volume limit in µl
16
+
17
+ struct Group {
18
+ ll mass, vol, value;
19
+ int type;
20
+ };
21
+
22
+ int main() {
23
+ // Read entire input
24
+ string s;
25
+ char ch;
26
+ while (cin.get(ch)) s += ch;
27
+
28
+ // Parse JSON
29
+ vector<string> names;
30
+ vector<ll> q, v, m, l;
31
+ int pos = 0;
32
+ auto skip_ws = [&]() {
33
+ while (pos < (int)s.size() && isspace(s[pos])) pos++;
34
+ };
35
+ skip_ws();
36
+ if (s[pos] != '{') return 1;
37
+ pos++;
38
+ for (int i = 0; i < 12; ++i) {
39
+ skip_ws();
40
+ if (s[pos] != '"') return 1;
41
+ pos++;
42
+ string key;
43
+ while (pos < (int)s.size() && s[pos] != '"') key += s[pos++];
44
+ if (s[pos] != '"') return 1;
45
+ pos++;
46
+ skip_ws();
47
+ if (s[pos] != ':') return 1;
48
+ pos++;
49
+ skip_ws();
50
+ if (s[pos] != '[') return 1;
51
+ pos++;
52
+ vector<ll> nums;
53
+ for (int j = 0; j < 4; ++j) {
54
+ skip_ws();
55
+ ll num = 0;
56
+ bool neg = false;
57
+ if (s[pos] == '-') { neg = true; pos++; }
58
+ while (pos < (int)s.size() && isdigit(s[pos])) {
59
+ num = num * 10 + (s[pos] - '0');
60
+ pos++;
61
+ }
62
+ if (neg) num = -num;
63
+ nums.push_back(num);
64
+ skip_ws();
65
+ if (j < 3) {
66
+ if (s[pos] != ',') return 1;
67
+ pos++;
68
+ }
69
+ }
70
+ skip_ws();
71
+ if (s[pos] != ']') return 1;
72
+ pos++;
73
+ skip_ws();
74
+ if (i < 11) {
75
+ if (s[pos] != ',') return 1;
76
+ pos++;
77
+ }
78
+ names.push_back(key);
79
+ q.push_back(nums[0]);
80
+ v.push_back(nums[1]);
81
+ m.push_back(nums[2]);
82
+ l.push_back(nums[3]);
83
+ }
84
+ skip_ws();
85
+ if (s[pos] != '}') return 1;
86
+
87
+ int n = 12;
88
+
89
+ // Precompute mask values
90
+ int total_masks = 1 << n;
91
+ vector<ll> mass_mask(total_masks, 0), vol_mask(total_masks, 0), value_mask(total_masks, 0);
92
+ for (int mask = 0; mask < total_masks; ++mask) {
93
+ ll mass = 0, vol = 0, val = 0;
94
+ for (int i = 0; i < n; ++i) {
95
+ if (mask & (1 << i)) {
96
+ mass += q[i] * m[i];
97
+ vol += q[i] * l[i];
98
+ val += q[i] * v[i];
99
+ }
100
+ }
101
+ mass_mask[mask] = mass;
102
+ vol_mask[mask] = vol;
103
+ value_mask[mask] = val;
104
+ }
105
+
106
+ // Best solution found
107
+ ll best_value = -1;
108
+ vector<ll> best_counts(n, 0);
109
+
110
+ // 1. All variables at bounds (0 or q[i])
111
+ for (int mask = 0; mask < total_masks; ++mask) {
112
+ if (mass_mask[mask] <= M && vol_mask[mask] <= L) {
113
+ if (value_mask[mask] > best_value) {
114
+ best_value = value_mask[mask];
115
+ for (int i = 0; i < n; ++i)
116
+ best_counts[i] = (mask & (1 << i)) ? q[i] : 0;
117
+ }
118
+ }
119
+ }
120
+
121
+ // 2. One free variable
122
+ for (int mask = 0; mask < total_masks; ++mask) {
123
+ for (int i = 0; i < n; ++i) {
124
+ int fixed_mask = mask & ~(1 << i);
125
+ ll mass_fixed = mass_mask[fixed_mask];
126
+ ll vol_fixed = vol_mask[fixed_mask];
127
+ ll value_fixed = value_mask[fixed_mask];
128
+ ll rm = M - mass_fixed;
129
+ ll rv = L - vol_fixed;
130
+ if (rm < 0 || rv < 0) continue;
131
+ ll max_xi = q[i];
132
+ if (m[i] > 0) max_xi = min(max_xi, rm / m[i]);
133
+ if (l[i] > 0) max_xi = min(max_xi, rv / l[i]);
134
+ if (max_xi >= 0) {
135
+ ll total_value = value_fixed + max_xi * v[i];
136
+ if (total_value > best_value) {
137
+ best_value = total_value;
138
+ for (int k = 0; k < n; ++k)
139
+ best_counts[k] = (fixed_mask & (1 << k)) ? q[k] : 0;
140
+ best_counts[i] = max_xi;
141
+ }
142
+ }
143
+ }
144
+ }
145
+
146
+ // 3. Two free variables
147
+ for (int mask = 0; mask < total_masks; ++mask) {
148
+ for (int i = 0; i < n; ++i) {
149
+ for (int j = i + 1; j < n; ++j) {
150
+ int fixed_mask = mask & ~(1 << i) & ~(1 << j);
151
+ ll mass_fixed = mass_mask[fixed_mask];
152
+ ll vol_fixed = vol_mask[fixed_mask];
153
+ ll value_fixed = value_mask[fixed_mask];
154
+ ll M_res = M - mass_fixed;
155
+ ll L_res = L - vol_fixed;
156
+ if (M_res < 0 || L_res < 0) continue;
157
+ double det = (double)m[i] * l[j] - (double)m[j] * l[i];
158
+ if (fabs(det) < 1e-9) continue;
159
+ double xi_cont = (M_res * l[j] - L_res * m[j]) / det;
160
+ double xj_cont = (m[i] * L_res - l[i] * M_res) / det;
161
+ for (int xi_round = 0; xi_round <= 1; ++xi_round) {
162
+ ll xi = (xi_round == 0) ? (ll)floor(xi_cont) : (ll)ceil(xi_cont);
163
+ if (xi < 0) xi = 0;
164
+ if (xi > q[i]) xi = q[i];
165
+ for (int xj_round = 0; xj_round <= 1; ++xj_round) {
166
+ ll xj = (xj_round == 0) ? (ll)floor(xj_cont) : (ll)ceil(xj_cont);
167
+ if (xj < 0) xj = 0;
168
+ if (xj > q[j]) xj = q[j];
169
+ ll mass = mass_fixed + xi * m[i] + xj * m[j];
170
+ ll volume = vol_fixed + xi * l[i] + xj * l[j];
171
+ if (mass <= M && volume <= L) {
172
+ ll total_value = value_fixed + xi * v[i] + xj * v[j];
173
+ if (total_value > best_value) {
174
+ best_value = total_value;
175
+ for (int k = 0; k < n; ++k)
176
+ best_counts[k] = (fixed_mask & (1 << k)) ? q[k] : 0;
177
+ best_counts[i] = xi;
178
+ best_counts[j] = xj;
179
+ }
180
+ }
181
+ }
182
+ }
183
+ }
184
+ }
185
+ }
186
+
187
+ // Try to improve the solution by filling remaining capacity
188
+ ll total_mass = 0, total_vol = 0;
189
+ for (int i = 0; i < n; ++i) {
190
+ total_mass += best_counts[i] * m[i];
191
+ total_vol += best_counts[i] * l[i];
192
+ }
193
+ ll rm = M - total_mass;
194
+ ll rv = L - total_vol;
195
+
196
+ if (rm > 0 && rv > 0) {
197
+ // If remaining capacities are small, use DP
198
+ if (rm <= 2000 && rv <= 2500) {
199
+ vector<Group> groups;
200
+ for (int i = 0; i < n; ++i) {
201
+ ll rq_i = q[i] - best_counts[i];
202
+ if (rq_i <= 0) continue;
203
+ ll k = rq_i;
204
+ for (ll p = 1; p <= k; p <<= 1) {
205
+ ll take = min(p, k);
206
+ groups.push_back({ m[i] * take, l[i] * take, v[i] * take, i });
207
+ k -= take;
208
+ }
209
+ }
210
+ int RM = (int)rm;
211
+ int RV = (int)rv;
212
+ vector<vector<ll>> dp(RM + 1, vector<ll>(RV + 1, -1));
213
+ vector<vector<int>> from_group(RM + 1, vector<int>(RV + 1, -1));
214
+ dp[0][0] = 0;
215
+ for (int g = 0; g < (int)groups.size(); ++g) {
216
+ Group &gr = groups[g];
217
+ if (gr.mass > RM || gr.vol > RV) continue;
218
+ for (int x = RM; x >= gr.mass; --x) {
219
+ for (int y = RV; y >= gr.vol; --y) {
220
+ if (dp[x - gr.mass][y - gr.vol] != -1) {
221
+ ll new_val = dp[x - gr.mass][y - gr.vol] + gr.value;
222
+ if (new_val > dp[x][y]) {
223
+ dp[x][y] = new_val;
224
+ from_group[x][y] = g;
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ // Find best additional value
231
+ ll best_add = 0;
232
+ int best_x = 0, best_y = 0;
233
+ for (int x = 0; x <= RM; ++x) {
234
+ for (int y = 0; y <= RV; ++y) {
235
+ if (dp[x][y] > best_add) {
236
+ best_add = dp[x][y];
237
+ best_x = x;
238
+ best_y = y;
239
+ }
240
+ }
241
+ }
242
+ if (best_add > 0) {
243
+ vector<ll> add_counts(n, 0);
244
+ int x = best_x, y = best_y;
245
+ while (from_group[x][y] != -1) {
246
+ int g = from_group[x][y];
247
+ add_counts[groups[g].type] += groups[g].value / v[groups[g].type];
248
+ int nx = x - groups[g].mass;
249
+ int ny = y - groups[g].vol;
250
+ x = nx; y = ny;
251
+ }
252
+ for (int i = 0; i < n; ++i) {
253
+ best_counts[i] += add_counts[i];
254
+ best_value += add_counts[i] * v[i];
255
+ }
256
+ }
257
+ } else {
258
+ // Greedy fill based on value density
259
+ vector<int> indices;
260
+ for (int i = 0; i < n; ++i)
261
+ if (best_counts[i] < q[i]) indices.push_back(i);
262
+ sort(indices.begin(), indices.end(), [&](int a, int b) {
263
+ double den_a = (double)v[a] / ( (double)m[a]/M + (double)l[a]/L );
264
+ double den_b = (double)v[b] / ( (double)m[b]/M + (double)l[b]/L );
265
+ return den_a > den_b;
266
+ });
267
+ vector<ll> temp_counts = best_counts;
268
+ ll temp_mass = total_mass, temp_vol = total_vol;
269
+ ll temp_rm = rm, temp_rv = rv;
270
+ for (int i : indices) {
271
+ ll can_add = min(q[i] - temp_counts[i],
272
+ min(temp_rm / m[i], temp_rv / l[i]));
273
+ if (can_add > 0) {
274
+ temp_counts[i] += can_add;
275
+ temp_mass += can_add * m[i];
276
+ temp_vol += can_add * l[i];
277
+ temp_rm -= can_add * m[i];
278
+ temp_rv -= can_add * l[i];
279
+ }
280
+ }
281
+ ll temp_value = 0;
282
+ for (int i = 0; i < n; ++i) temp_value += temp_counts[i] * v[i];
283
+ if (temp_value > best_value) {
284
+ best_value = temp_value;
285
+ best_counts = temp_counts;
286
+ }
287
+ }
288
+ }
289
+
290
+ // Output JSON
291
+ cout << "{\n";
292
+ for (int i = 0; i < n; ++i) {
293
+ cout << " \"" << names[i] << "\": " << best_counts[i];
294
+ if (i != n - 1) cout << ",";
295
+ cout << "\n";
296
+ }
297
+ cout << "}\n";
298
+
299
+ return 0;
300
+ }
docker_space/frontier_cs_1/examples/gemini2.5pro.cpp ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <string>
3
+ #include <vector>
4
+ #include <map>
5
+ #include <algorithm>
6
+ #include <array>
7
+ #include <nlohmann/json.hpp>
8
+
9
+ using json = nlohmann::json;
10
+
11
+ const long long W_MASS = 20000000;
12
+ const long long W_VOL = 25000000;
13
+ const int N_ITEMS = 12;
14
+
15
+ struct Item {
16
+ std::string name;
17
+ int q;
18
+ long long v, m, l;
19
+ int original_idx;
20
+ };
21
+
22
+ struct State {
23
+ long long m = 0, l = 0, v = 0;
24
+ std::vector<int> counts;
25
+
26
+ bool operator<(const State& other) const {
27
+ if (m != other.m) return m < other.m;
28
+ if (l != other.l) return l < other.l;
29
+ return v > other.v; // for sorting, higher value is better
30
+ }
31
+ };
32
+
33
+ std::vector<State> prune(std::vector<State>& states) {
34
+ if (states.size() <= 1) return states;
35
+
36
+ std::sort(states.begin(), states.end(), [](const State& a, const State& b){
37
+ return a.v > b.v;
38
+ });
39
+
40
+ std::vector<State> final_pruned;
41
+ final_pruned.reserve(states.size());
42
+
43
+ for(const auto& s : states) {
44
+ bool dominated = false;
45
+ for(const auto& p : final_pruned) {
46
+ if (p.m <= s.m && p.l <= s.l) { // p.v >= s.v is guaranteed by sort order
47
+ dominated = true;
48
+ break;
49
+ }
50
+ }
51
+ if (!dominated) {
52
+ final_pruned.push_back(s);
53
+ }
54
+ }
55
+ return final_pruned;
56
+ }
57
+
58
+ std::vector<State> generate_states(const std::vector<Item>& items, int state_limit) {
59
+ int n = items.size();
60
+ if (n == 0) {
61
+ std::vector<State> res;
62
+ res.emplace_back();
63
+ res.back().counts.resize(0);
64
+ return res;
65
+ }
66
+
67
+ std::vector<State> states;
68
+ states.emplace_back();
69
+ states.back().counts.resize(n, 0);
70
+
71
+ for (int i = 0; i < n; ++i) {
72
+ std::vector<State> next_states;
73
+ int q_eff = items[i].q;
74
+ // Heuristic cap to prevent state explosion
75
+ if (q_eff > 30) q_eff = 30;
76
+
77
+ next_states.reserve(states.size() * (q_eff + 1));
78
+
79
+ for (const auto& s : states) {
80
+ for (int c = 0; c <= q_eff; ++c) {
81
+ long long next_m = s.m + c * items[i].m;
82
+ long long next_l = s.l + c * items[i].l;
83
+ if (next_m > W_MASS || next_l > W_VOL) {
84
+ break;
85
+ }
86
+ State next_s;
87
+ next_s.m = next_m;
88
+ next_s.l = next_l;
89
+ next_s.v = s.v + c * items[i].v;
90
+ next_s.counts = s.counts;
91
+ next_s.counts[i] = c;
92
+ next_states.push_back(next_s);
93
+ }
94
+ }
95
+
96
+ states = prune(next_states);
97
+ if (states.size() > state_limit) {
98
+ std::sort(states.begin(), states.end(), [](const State& a, const State& b){
99
+ return a.v > b.v;
100
+ });
101
+ states.resize(state_limit);
102
+ }
103
+ }
104
+ return states;
105
+ }
106
+
107
+ int main() {
108
+ std::ios_base::sync_with_stdio(false);
109
+ std::cin.tie(NULL);
110
+
111
+ json input_json;
112
+ std::cin >> input_json;
113
+
114
+ std::vector<Item> all_items;
115
+ int idx_counter = 0;
116
+ for (auto& [name, val] : input_json.items()) {
117
+ all_items.push_back({
118
+ name,
119
+ val[0].get<int>(),
120
+ val[1].get<long long>(),
121
+ val[2].get<long long>(),
122
+ val[3].get<long long>(),
123
+ idx_counter++
124
+ });
125
+ }
126
+
127
+ std::vector<Item> lumpy_items, dust_items;
128
+
129
+ for (const auto& item : all_items) {
130
+ if (item.q > 50 && (item.m < 100000 || item.l < 100000)) {
131
+ dust_items.push_back(item);
132
+ } else {
133
+ lumpy_items.push_back(item);
134
+ }
135
+ }
136
+
137
+ std::sort(dust_items.begin(), dust_items.end(), [](const Item& a, const Item& b) {
138
+ double dens_a = (double)a.v / (a.m / (double)W_MASS * 0.5 + a.l / (double)W_VOL * 0.5 + 1e-9);
139
+ double dens_b = (double)b.v / (b.m / (double)W_MASS * 0.5 + b.l / (double)W_VOL * 0.5 + 1e-9);
140
+ return dens_a > dens_b;
141
+ });
142
+
143
+ std::vector<Item> lumpy_a, lumpy_b;
144
+ for (size_t i = 0; i < lumpy_items.size(); ++i) {
145
+ if (i < lumpy_items.size() / 2) {
146
+ lumpy_a.push_back(lumpy_items[i]);
147
+ } else {
148
+ lumpy_b.push_back(lumpy_items[i]);
149
+ }
150
+ }
151
+
152
+ int state_limit = 4000;
153
+ auto states_a = generate_states(lumpy_a, state_limit);
154
+ auto states_b = generate_states(lumpy_b, state_limit);
155
+
156
+ long long max_total_value = -1;
157
+ std::vector<int> best_counts(N_ITEMS, 0);
158
+
159
+ for (const auto& s_a : states_a) {
160
+ for (const auto& s_b : states_b) {
161
+ long long current_m = s_a.m + s_b.m;
162
+ long long current_l = s_a.l + s_b.l;
163
+
164
+ if (current_m > W_MASS || current_l > W_VOL) continue;
165
+
166
+ long long current_v = s_a.v + s_b.v;
167
+ std::vector<int> current_counts(N_ITEMS, 0);
168
+
169
+ for (size_t i = 0; i < lumpy_a.size(); ++i) current_counts[lumpy_a[i].original_idx] = s_a.counts[i];
170
+ for (size_t i = 0; i < lumpy_b.size(); ++i) current_counts[lumpy_b[i].original_idx] = s_b.counts[i];
171
+
172
+ long long m_rem = W_MASS - current_m;
173
+ long long l_rem = W_VOL - current_l;
174
+ long long dust_v = 0;
175
+
176
+ for (const auto& item : dust_items) {
177
+ int num_to_take = item.q;
178
+ if (item.m > 0) num_to_take = std::min(num_to_take, (int)(m_rem / item.m));
179
+ if (item.l > 0) num_to_take = std::min(num_to_take, (int)(l_rem / item.l));
180
+
181
+ if (num_to_take > 0) {
182
+ m_rem -= (long long)num_to_take * item.m;
183
+ l_rem -= (long long)num_to_take * item.l;
184
+ dust_v += (long long)num_to_take * item.v;
185
+ current_counts[item.original_idx] += num_to_take;
186
+ }
187
+ }
188
+
189
+ if (current_v + dust_v > max_total_value) {
190
+ max_total_value = current_v + dust_v;
191
+ best_counts = current_counts;
192
+ }
193
+ }
194
+ }
195
+
196
+ // A pure greedy solution on all items as a baseline
197
+ {
198
+ long long m_rem = W_MASS;
199
+ long long l_rem = W_VOL;
200
+ long long current_v = 0;
201
+ std::vector<int> current_counts(N_ITEMS, 0);
202
+ std::vector<Item> sorted_all = all_items;
203
+ std::sort(sorted_all.begin(), sorted_all.end(), [](const Item& a, const Item& b) {
204
+ double dens_a = (double)a.v / (a.m / (double)W_MASS * 0.5 + a.l / (double)W_VOL * 0.5 + 1e-9);
205
+ double dens_b = (double)b.v / (b.m / (double)W_MASS * 0.5 + b.l / (double)W_VOL * 0.5 + 1e-9);
206
+ return dens_a > dens_b;
207
+ });
208
+
209
+ for (const auto& item : sorted_all) {
210
+ int num_to_take = item.q;
211
+ if (item.m > 0) num_to_take = std::min(num_to_take, (int)(m_rem / item.m));
212
+ if (item.l > 0) num_to_take = std::min(num_to_take, (int)(l_rem / item.l));
213
+
214
+ if (num_to_take > 0) {
215
+ m_rem -= (long long)num_to_take * item.m;
216
+ l_rem -= (long long)num_to_take * item.l;
217
+ current_v += (long long)num_to_take * item.v;
218
+ current_counts[item.original_idx] = num_to_take;
219
+ }
220
+ }
221
+ if (current_v > max_total_value) {
222
+ best_counts = current_counts;
223
+ }
224
+ }
225
+
226
+ json output_json;
227
+ for (int i = 0; i < N_ITEMS; ++i) {
228
+ output_json[all_items[i].name] = best_counts[i];
229
+ }
230
+
231
+ std::cout << output_json.dump(1, '\t') << std::endl;
232
+
233
+ return 0;
234
+ }
docker_space/frontier_cs_1/examples/gemini2.5pro_2.cpp ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <string>
3
+ #include <vector>
4
+ #include <algorithm>
5
+ #include <map>
6
+ #include <functional>
7
+
8
+ // To create a single-file solution, the content of nlohmann/json.hpp is included here.
9
+ // This is a placeholder for the actual header content.
10
+ #ifndef NLOHMANN_JSON_HPP
11
+ #include "json.hpp" // Assumes json.hpp is in the same directory or in include path.
12
+ #endif
13
+
14
+
15
+ using json = nlohmann::json;
16
+ using ll = long long;
17
+
18
+ const ll M_CAP = 20000000;
19
+ const ll L_CAP = 25000000;
20
+
21
+ struct Item {
22
+ std::string name;
23
+ int id;
24
+ int q;
25
+ ll v, m, l;
26
+ double density;
27
+ };
28
+
29
+ std::vector<Item> all_items;
30
+ std::vector<Item> large_items, small_items;
31
+
32
+ ll max_total_value = -1;
33
+ std::vector<int> best_counts;
34
+
35
+ ll states_visited = 0;
36
+ const ll MAX_STATES_PER_RUN = 5000000;
37
+
38
+ void solve(int large_item_idx, ll current_m, ll current_l, ll current_v, std::vector<int>& current_counts) {
39
+ if (states_visited++ > MAX_STATES_PER_RUN) {
40
+ return;
41
+ }
42
+
43
+ if (large_item_idx == large_items.size()) {
44
+ ll rem_m = M_CAP - current_m;
45
+ ll rem_l = L_CAP - current_l;
46
+ ll total_v = current_v;
47
+
48
+ std::vector<int> final_counts = current_counts;
49
+
50
+ for (const auto& s_item : small_items) {
51
+ final_counts[s_item.id] = 0; // Ensure small item counts are reset for this path
52
+ if (s_item.m <= 0 && s_item.l <= 0) continue;
53
+
54
+ ll can_take = s_item.q;
55
+ if (s_item.m > 0) can_take = std::min(can_take, rem_m / s_item.m);
56
+ if (s_item.l > 0) can_take = std::min(can_take, rem_l / s_item.l);
57
+
58
+ if (can_take > 0) {
59
+ rem_m -= can_take * s_item.m;
60
+ rem_l -= can_take * s_item.l;
61
+ total_v += can_take * s_item.v;
62
+ final_counts[s_item.id] = can_take;
63
+ }
64
+ }
65
+
66
+ if (total_v > max_total_value) {
67
+ max_total_value = total_v;
68
+ best_counts = final_counts;
69
+ }
70
+ return;
71
+ }
72
+
73
+ const auto& l_item = large_items[large_item_idx];
74
+ ll max_k = l_item.q;
75
+ if (l_item.m > 0) max_k = std::min(max_k, (M_CAP - current_m) / l_item.m);
76
+ if (l_item.l > 0) max_k = std::min(max_k, (L_CAP - current_l) / l_item.l);
77
+
78
+ for (ll k = max_k; k >= 0; --k) { // Iterate downwards to prioritize fuller bags
79
+ current_counts[l_item.id] = k;
80
+ solve(large_item_idx + 1,
81
+ current_m + k * l_item.m,
82
+ current_l + k * l_item.l,
83
+ current_v + k * l_item.v,
84
+ current_counts);
85
+ if (states_visited > MAX_STATES_PER_RUN) return;
86
+ }
87
+ current_counts[l_item.id] = 0;
88
+ }
89
+
90
+ int main() {
91
+ std::ios_base::sync_with_stdio(false);
92
+ std::cin.tie(NULL);
93
+
94
+ json input;
95
+ std::cin >> input;
96
+
97
+ int current_id = 0;
98
+ for (auto const& [name, val] : input.items()) {
99
+ all_items.push_back({
100
+ name,
101
+ current_id++,
102
+ val[0].get<int>(),
103
+ val[1].get<ll>(),
104
+ val[2].get<ll>(),
105
+ val[3].get<ll>(),
106
+ 0.0
107
+ });
108
+ }
109
+
110
+ ll m_thresh = M_CAP / 40;
111
+ ll l_thresh = L_CAP / 40;
112
+ for (const auto& item : all_items) {
113
+ if (item.m > m_thresh || item.l > l_thresh) {
114
+ large_items.push_back(item);
115
+ } else {
116
+ small_items.push_back(item);
117
+ }
118
+ }
119
+
120
+ best_counts.resize(all_items.size(), 0);
121
+ std::vector<int> current_counts(all_items.size(), 0);
122
+
123
+ for (int i = 0; i <= 10; ++i) {
124
+ double alpha = i / 10.0;
125
+
126
+ for (auto& item : small_items) {
127
+ if (alpha < 1e-9) {
128
+ item.density = (item.l > 0) ? (double)item.v / item.l : 1e18;
129
+ } else if (alpha > 1.0 - 1e-9) {
130
+ item.density = (item.m > 0) ? (double)item.v / item.m : 1e18;
131
+ } else {
132
+ double normalized_cost = alpha * (double)item.m / M_CAP + (1.0 - alpha) * (double)item.l / L_CAP;
133
+ item.density = (normalized_cost > 1e-12) ? (double)item.v / normalized_cost : 1e18;
134
+ }
135
+ }
136
+
137
+ std::sort(small_items.begin(), small_items.end(), [&](const Item& a, const Item& b) {
138
+ return a.density > b.density;
139
+ });
140
+
141
+ states_visited = 0;
142
+ solve(0, 0, 0, 0, current_counts);
143
+ }
144
+
145
+ auto run_greedy = [&](auto density_func) {
146
+ std::vector<Item> sorted_items = all_items;
147
+ std::sort(sorted_items.begin(), sorted_items.end(), [&](const Item& a, const Item& b) {
148
+ return density_func(a) > density_func(b);
149
+ });
150
+
151
+ std::vector<int> greedy_counts(all_items.size(), 0);
152
+ ll current_m = 0, current_l = 0, current_v = 0;
153
+
154
+ for (const auto& item : sorted_items) {
155
+ ll rem_m = M_CAP - current_m;
156
+ ll rem_l = L_CAP - current_l;
157
+ ll can_take = item.q;
158
+ if (item.m > 0) can_take = std::min(can_take, rem_m / item.m);
159
+ if (item.l > 0) can_take = std::min(can_take, rem_l / item.l);
160
+
161
+ if(can_take > 0) {
162
+ current_m += can_take * item.m;
163
+ current_l += can_take * item.l;
164
+ current_v += can_take * item.v;
165
+ greedy_counts[item.id] = can_take;
166
+ }
167
+ }
168
+ if (current_v > max_total_value) {
169
+ max_total_value = current_v;
170
+ best_counts = greedy_counts;
171
+ }
172
+ };
173
+
174
+ run_greedy([](const Item& i) { return (i.m > 0) ? (double)i.v / i.m : 1e18; });
175
+ run_greedy([](const Item& i) { return (i.l > 0) ? (double)i.v / i.l : 1e18; });
176
+ run_greedy([](const Item& i) { return (i.m + i.l > 0) ? (double)i.v / (double)(i.m + i.l) : 1e18; });
177
+
178
+ json output;
179
+ for (const auto& item : all_items) {
180
+ output[item.name] = best_counts[item.id];
181
+ }
182
+ std::cout << output.dump(2) << std::endl;
183
+
184
+ return 0;
185
+ }
docker_space/frontier_cs_1/examples/gemini2.5pro_3.cpp ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <vector>
3
+ #include <string>
4
+ #include <array>
5
+ #include <unordered_map>
6
+ #include <algorithm>
7
+ #include <utility>
8
+ #include "json.hpp"
9
+
10
+ using json = nlohmann::json;
11
+
12
+ const long long MAX_MASS = 20000000;
13
+ const long long MAX_VOLUME = 25000000;
14
+ const int NUM_ITEMS = 12;
15
+ const int HALF_NUM_ITEMS = 6;
16
+
17
+ struct Item {
18
+ std::string name;
19
+ int q;
20
+ long long v, m, l;
21
+ int original_idx;
22
+ };
23
+
24
+ struct State {
25
+ long long m, l, v;
26
+ std::array<int, HALF_NUM_ITEMS> counts;
27
+ };
28
+
29
+ struct pair_hash {
30
+ template <class T1, class T2>
31
+ std::size_t operator () (const std::pair<T1, T2>& p) const {
32
+ auto h1 = std::hash<T1>{}(p.first);
33
+ auto h2 = std::hash<T2>{}(p.second);
34
+ // A simple way to combine hashes, found to be effective in practice.
35
+ return h1 ^ (h2 << 1);
36
+ }
37
+ };
38
+
39
+ using StatesMap = std::unordered_map<std::pair<long long, long long>, std::pair<long long, std::array<int, HALF_NUM_ITEMS>>, pair_hash>;
40
+
41
+ StatesMap generate_states(const std::vector<Item>& items) {
42
+ StatesMap states;
43
+ states.reserve(100000); // Pre-allocation to reduce rehashes
44
+ states[{0, 0}] = {0, {}};
45
+
46
+ for (int i = 0; i < items.size(); ++i) {
47
+ const auto& item = items[i];
48
+ long long current_q = item.q;
49
+
50
+ std::vector<long long> meta_quantities;
51
+ for (long long p = 1; current_q > 0; p *= 2) {
52
+ long long take = std::min(p, current_q);
53
+ meta_quantities.push_back(take);
54
+ current_q -= take;
55
+ }
56
+
57
+ for (const auto& k : meta_quantities) {
58
+ long long delta_m = k * item.m;
59
+ long long delta_l = k * item.l;
60
+ long long delta_v = k * item.v;
61
+
62
+ std::vector<std::pair<std::pair<long long, long long>, std::pair<long long, std::array<int, HALF_NUM_ITEMS>>>> updates;
63
+ updates.reserve(states.size());
64
+
65
+ for (const auto& s : states) {
66
+ long long new_m = s.first.first + delta_m;
67
+ long long new_l = s.first.second + delta_l;
68
+
69
+ if (new_m <= MAX_MASS && new_l <= MAX_VOLUME) {
70
+ long long new_v = s.second.first + delta_v;
71
+ auto new_counts = s.second.second;
72
+ new_counts[i] += k;
73
+ updates.push_back({{new_m, new_l}, {new_v, new_counts}});
74
+ }
75
+ }
76
+
77
+ for (const auto& update : updates) {
78
+ const auto& key = update.first;
79
+ const auto& val = update.second;
80
+ auto it = states.find(key);
81
+ if (it == states.end() || it->second.first < val.first) {
82
+ states[key] = val;
83
+ }
84
+ }
85
+ }
86
+ }
87
+ return states;
88
+ }
89
+
90
+ std::vector<State> prune_and_convert(const StatesMap& states_map) {
91
+ std::vector<State> states_vec;
92
+ states_vec.reserve(states_map.size());
93
+ for (const auto& pair : states_map) {
94
+ states_vec.push_back({pair.first.first, pair.first.second, pair.second.first, pair.second.second});
95
+ }
96
+
97
+ std::sort(states_vec.begin(), states_vec.end(), [](const State& a, const State& b) {
98
+ if (a.m != b.m) return a.m < b.m;
99
+ if (a.l != b.l) return a.l < b.l;
100
+ return a.v > b.v;
101
+ });
102
+
103
+ std::vector<State> pruned;
104
+ pruned.reserve(states_vec.size());
105
+ for (const auto& s : states_vec) {
106
+ while (!pruned.empty() && pruned.back().l >= s.l && pruned.back().v <= s.v) {
107
+ pruned.pop_back();
108
+ }
109
+ if (pruned.empty() || pruned.back().l < s.l || pruned.back().v < s.v) {
110
+ pruned.push_back(s);
111
+ }
112
+ }
113
+ return pruned;
114
+ }
115
+
116
+ int main() {
117
+ std::ios_base::sync_with_stdio(false);
118
+ std::cin.tie(NULL);
119
+
120
+ json input_json;
121
+ std::cin >> input_json;
122
+
123
+ std::vector<Item> all_items;
124
+ int idx = 0;
125
+ for (auto& [key, value] : input_json.items()) {
126
+ all_items.push_back({key, value[0], value[1], value[2], value[3], idx++});
127
+ }
128
+
129
+ std::sort(all_items.begin(), all_items.end(), [](const Item& a, const Item& b){
130
+ return a.name < b.name;
131
+ });
132
+
133
+ std::vector<Item> groupA(all_items.begin(), all_items.begin() + HALF_NUM_ITEMS);
134
+ std::vector<Item> groupB(all_items.begin() + HALF_NUM_ITEMS, all_items.end());
135
+
136
+ StatesMap states_map_A = generate_states(groupA);
137
+ StatesMap states_map_B = generate_states(groupB);
138
+
139
+ std::vector<State> listA = prune_and_convert(states_map_A);
140
+ std::vector<State> listB = prune_and_convert(states_map_B);
141
+
142
+ std::sort(listA.begin(), listA.end(), [](const State& a, const State& b) {
143
+ return a.m < b.m;
144
+ });
145
+ std::sort(listB.begin(), listB.end(), [](const State& a, const State& b) {
146
+ return a.m < b.m;
147
+ });
148
+
149
+ long long max_val = 0;
150
+ std::array<int, NUM_ITEMS> best_counts = {};
151
+
152
+ int ptrB = listB.size() - 1;
153
+ for (const auto& s_a : listA) {
154
+ while (ptrB >= 0 && s_a.m + listB[ptrB].m > MAX_MASS) {
155
+ ptrB--;
156
+ }
157
+ if (ptrB < 0) {
158
+ break;
159
+ }
160
+
161
+ for (int i = 0; i <= ptrB; ++i) {
162
+ const auto& s_b = listB[i];
163
+ if (s_a.l + s_b.l <= MAX_VOLUME) {
164
+ if (s_a.v + s_b.v > max_val) {
165
+ max_val = s_a.v + s_b.v;
166
+ for (int j = 0; j < HALF_NUM_ITEMS; ++j) {
167
+ best_counts[groupA[j].original_idx] = s_a.counts[j];
168
+ }
169
+ for (int j = 0; j < HALF_NUM_ITEMS; ++j) {
170
+ best_counts[groupB[j].original_idx] = s_b.counts[j];
171
+ }
172
+ }
173
+ }
174
+ }
175
+ }
176
+
177
+ json output_json;
178
+ for(int i = 0; i < NUM_ITEMS; ++i) {
179
+ output_json[all_items[i].name] = best_counts[i];
180
+ }
181
+ std::cout << output_json.dump(1, '\t') << std::endl;
182
+
183
+ return 0;
184
+ }
docker_space/frontier_cs_1/examples/gemini2.5pro_4.cpp ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <vector>
3
+ #include <string>
4
+ #include <algorithm>
5
+ #include <map>
6
+ #include <set>
7
+ #include <random>
8
+ #include <chrono>
9
+ #include <nlohmann/json.hpp>
10
+
11
+ using json = nlohmann::json;
12
+
13
+ struct Item {
14
+ std::string name;
15
+ int q;
16
+ long long v, m, l;
17
+ double density;
18
+ int original_idx;
19
+ };
20
+
21
+ // Global constants
22
+ const long long MAX_MASS = 20000000;
23
+ const long long MAX_VOL = 25000000;
24
+
25
+ int main() {
26
+ std::ios_base::sync_with_stdio(false);
27
+ std::cin.tie(NULL);
28
+
29
+ json input_json;
30
+ std::cin >> input_json;
31
+
32
+ std::vector<Item> original_items;
33
+ std::vector<std::string> key_order;
34
+ int idx_counter = 0;
35
+ for (auto& el : input_json.items()) {
36
+ key_order.push_back(el.key());
37
+ auto& props = el.value();
38
+ original_items.push_back({
39
+ el.key(),
40
+ (int)props[0],
41
+ (long long)props[1],
42
+ (long long)props[2],
43
+ (long long)props[3],
44
+ 0.0,
45
+ idx_counter++
46
+ });
47
+ }
48
+
49
+ std::set<double> c_values_set;
50
+ c_values_set.insert(0.0);
51
+ c_values_set.insert(1.0);
52
+ for (size_t i = 0; i < original_items.size(); ++i) {
53
+ for (size_t j = i + 1; j < original_items.size(); ++j) {
54
+ auto& item1 = original_items[i];
55
+ auto& item2 = original_items[j];
56
+ long long v1 = item1.v, m1 = item1.m, l1 = item1.l;
57
+ long long v2 = item2.v, m2 = item2.m, l2 = item2.l;
58
+
59
+ double num = (double)v2 * l1 - (double)v1 * l2;
60
+ double den = (double)v1 * (m2 - l2) - (double)v2 * (m1 - l1);
61
+
62
+ if (std::abs(den) > 1e-9) {
63
+ double c = num / den;
64
+ if (c > 1e-9 && c < 1.0 - 1e-9) {
65
+ c_values_set.insert(c);
66
+ }
67
+ }
68
+ }
69
+ }
70
+
71
+ std::vector<double> test_cs;
72
+ for (double c : c_values_set) {
73
+ test_cs.push_back(c);
74
+ if (c > 1e-9) test_cs.push_back(c - 1e-9);
75
+ if (c < 1.0 - 1e-9) test_cs.push_back(c + 1e-9);
76
+ }
77
+ std::sort(test_cs.begin(), test_cs.end());
78
+ test_cs.erase(std::unique(test_cs.begin(), test_cs.end()), test_cs.end());
79
+
80
+ long long best_total_value = -1;
81
+ std::vector<int> best_counts(original_items.size());
82
+ double best_c = -1.0;
83
+
84
+ for (double c : test_cs) {
85
+ if (c < 0 || c > 1) continue;
86
+ std::vector<Item> current_items = original_items;
87
+ for (auto& item : current_items) {
88
+ double cost = c * item.m + (1.0 - c) * item.l;
89
+ if (cost < 1e-9) {
90
+ item.density = 1e18; // Effectively infinite
91
+ } else {
92
+ item.density = (double)item.v / cost;
93
+ }
94
+ }
95
+
96
+ std::sort(current_items.begin(), current_items.end(), [](const Item& a, const Item& b) {
97
+ return a.density > b.density;
98
+ });
99
+
100
+ long long current_m = 0;
101
+ long long current_l = 0;
102
+ long long current_v = 0;
103
+ std::vector<int> current_counts(original_items.size(), 0);
104
+
105
+ for (const auto& item : current_items) {
106
+ long long can_take = item.q;
107
+ if (item.m > 0) can_take = std::min(can_take, (MAX_MASS - current_m) / item.m);
108
+ if (item.l > 0) can_take = std::min(can_take, (MAX_VOL - current_l) / item.l);
109
+
110
+ if (can_take > 0) {
111
+ current_m += can_take * item.m;
112
+ current_l += can_take * item.l;
113
+ current_v += can_take * item.v;
114
+ current_counts[item.original_idx] = can_take;
115
+ }
116
+ }
117
+
118
+ if (current_v > best_total_value) {
119
+ best_total_value = current_v;
120
+ best_counts = current_counts;
121
+ best_c = c;
122
+ }
123
+ }
124
+
125
+ // Local Search to improve the best solution
126
+ if (best_c >= 0) {
127
+ std::vector<Item> sorted_by_best_c = original_items;
128
+ for (auto& item : sorted_by_best_c) {
129
+ double cost = best_c * item.m + (1.0 - best_c) * item.l;
130
+ if (cost < 1e-9) item.density = 1e18;
131
+ else item.density = (double)item.v / cost;
132
+ }
133
+ std::sort(sorted_by_best_c.begin(), sorted_by_best_c.end(), [](const Item& a, const Item& b) {
134
+ return a.density > b.density;
135
+ });
136
+
137
+ long long current_m = 0;
138
+ long long current_l = 0;
139
+ for (size_t i = 0; i < original_items.size(); ++i) {
140
+ current_m += (long long)best_counts[i] * original_items[i].m;
141
+ current_l += (long long)best_counts[i] * original_items[i].l;
142
+ }
143
+
144
+ std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
145
+
146
+ // Iteration limit is heuristic.
147
+ for (int iter = 0; iter < 100000; ++iter) {
148
+ std::vector<int> present_items_indices;
149
+ for (size_t i = 0; i < best_counts.size(); ++i) {
150
+ if (best_counts[i] > 0) {
151
+ present_items_indices.push_back(i);
152
+ }
153
+ }
154
+ if (present_items_indices.empty()) break;
155
+
156
+ std::uniform_int_distribution<int> dist(0, present_items_indices.size() - 1);
157
+ int idx_to_remove = present_items_indices[dist(rng)];
158
+
159
+ long long temp_m = current_m - original_items[idx_to_remove].m;
160
+ long long temp_l = current_l - original_items[idx_to_remove].l;
161
+ long long temp_v = best_total_value - original_items[idx_to_remove].v;
162
+ std::vector<int> temp_counts = best_counts;
163
+ temp_counts[idx_to_remove]--;
164
+
165
+ for (const auto& item : sorted_by_best_c) {
166
+ long long can_take = item.q - temp_counts[item.original_idx];
167
+ if (can_take <= 0) continue;
168
+ if (item.m > 0) can_take = std::min(can_take, (MAX_MASS - temp_m) / item.m);
169
+ if (item.l > 0) can_take = std::min(can_take, (MAX_VOL - temp_l) / item.l);
170
+
171
+ if (can_take > 0) {
172
+ temp_m += can_take * item.m;
173
+ temp_l += can_take * item.l;
174
+ temp_v += can_take * item.v;
175
+ temp_counts[item.original_idx] += can_take;
176
+ }
177
+ }
178
+
179
+ if (temp_v > best_total_value) {
180
+ best_total_value = temp_v;
181
+ best_counts = temp_counts;
182
+ current_m = temp_m;
183
+ current_l = temp_l;
184
+ }
185
+ }
186
+ }
187
+
188
+ json output_json;
189
+ for (const auto& key : key_order) {
190
+ bool found = false;
191
+ for (size_t i=0; i < original_items.size(); ++i) {
192
+ if (original_items[i].name == key) {
193
+ output_json[key] = best_counts[i];
194
+ found = true;
195
+ break;
196
+ }
197
+ }
198
+ }
199
+
200
+ std::cout << output_json.dump(2) << std::endl;
201
+
202
+ return 0;
203
+ }
docker_space/frontier_cs_1/examples/gemini3pro.cpp ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <vector>
3
+ #include <string>
4
+ #include <algorithm>
5
+ #include <map>
6
+ #include <ctime>
7
+ #include <cstdlib>
8
+
9
+ using namespace std;
10
+
11
+ // Structure to represent each treasure category
12
+ struct Item {
13
+ string name;
14
+ int id;
15
+ long long q; // quantity
16
+ long long v; // value
17
+ long long m; // mass
18
+ long long l; // volume
19
+ };
20
+
21
+ // Global capacity constraints
22
+ const long long MAX_M = 20000000; // 20 kg in mg
23
+ const long long MAX_L = 25000000; // 25 L in uL
24
+
25
+ // Structure to represent a solution state
26
+ struct Solution {
27
+ vector<int> counts;
28
+ long long total_v;
29
+ long long total_m;
30
+ long long total_l;
31
+
32
+ Solution(int n) : counts(n, 0), total_v(0), total_m(0), total_l(0) {}
33
+ };
34
+
35
+ vector<Item> items;
36
+ int N;
37
+
38
+ // Parse the JSON-like input
39
+ void parseInput() {
40
+ string input, line;
41
+ // Read all stdin into a single string
42
+ while (getline(cin, line)) {
43
+ input += line + " ";
44
+ }
45
+
46
+ vector<string> tokens;
47
+ string current;
48
+ bool inQuotes = false;
49
+ for (char c : input) {
50
+ if (inQuotes) {
51
+ if (c == '"') {
52
+ inQuotes = false;
53
+ if (!current.empty()) tokens.push_back(current);
54
+ current = "";
55
+ } else {
56
+ current += c;
57
+ }
58
+ } else {
59
+ if (c == '"') {
60
+ inQuotes = true;
61
+ } else if (isdigit(c) || c == '-') {
62
+ current += c;
63
+ } else {
64
+ if (!current.empty()) {
65
+ tokens.push_back(current);
66
+ current = "";
67
+ }
68
+ }
69
+ }
70
+ }
71
+ if (!current.empty()) tokens.push_back(current);
72
+
73
+ // Tokens are expected in groups of 5: Key, q, v, m, l
74
+ for (size_t i = 0; i < tokens.size(); i += 5) {
75
+ if (i + 4 >= tokens.size()) break;
76
+ Item item;
77
+ item.name = tokens[i];
78
+ item.id = (int)items.size();
79
+ item.q = stoll(tokens[i+1]);
80
+ item.v = stoll(tokens[i+2]);
81
+ item.m = stoll(tokens[i+3]);
82
+ item.l = stoll(tokens[i+4]);
83
+ items.push_back(item);
84
+ }
85
+ N = (int)items.size();
86
+ }
87
+
88
+ // Greedily fill the bag based on a specific item order
89
+ void fillGreedy(Solution& sol, const vector<int>& order) {
90
+ for (int idx : order) {
91
+ if (sol.counts[idx] >= items[idx].q) continue;
92
+
93
+ long long rem_m = MAX_M - sol.total_m;
94
+ long long rem_l = MAX_L - sol.total_l;
95
+
96
+ if (rem_m < items[idx].m || rem_l < items[idx].l) continue;
97
+
98
+ long long take_m = rem_m / items[idx].m;
99
+ long long take_l = rem_l / items[idx].l;
100
+ long long take_q = items[idx].q - sol.counts[idx];
101
+
102
+ long long count = min({take_m, take_l, take_q});
103
+
104
+ if (count > 0) {
105
+ sol.counts[idx] += count;
106
+ sol.total_v += count * items[idx].v;
107
+ sol.total_m += count * items[idx].m;
108
+ sol.total_l += count * items[idx].l;
109
+ }
110
+ }
111
+ }
112
+
113
+ int main() {
114
+ ios_base::sync_with_stdio(false);
115
+ cin.tie(NULL);
116
+ srand((unsigned)time(NULL));
117
+
118
+ parseInput();
119
+
120
+ if (N == 0) {
121
+ cout << "{}" << endl;
122
+ return 0;
123
+ }
124
+
125
+ double start_time = (double)clock() / CLOCKS_PER_SEC;
126
+
127
+ Solution bestSol(N);
128
+
129
+ int iterations = 0;
130
+ // Keep trying to improve the solution until time limit approaches
131
+ while (true) {
132
+ iterations++;
133
+ // Check time every 50 iterations to avoid overhead
134
+ if (iterations % 50 == 0) {
135
+ double curr_time = (double)clock() / CLOCKS_PER_SEC;
136
+ if (curr_time - start_time > 0.95) break;
137
+ }
138
+
139
+ // Generate a random tradeoff parameter alpha between mass and volume
140
+ double alpha = (double)rand() / RAND_MAX;
141
+
142
+ // Ensure we test pure Mass and pure Volume heuristics occasionally
143
+ if (iterations == 1) alpha = 0.0;
144
+ else if (iterations == 2) alpha = 1.0;
145
+ else if (iterations == 3) alpha = 0.5;
146
+
147
+ // Calculate score for each item based on value per weighted resource usage
148
+ vector<pair<double, int>> density(N);
149
+ for (int i = 0; i < N; ++i) {
150
+ // Normalize costs to capacity to make alpha meaningful
151
+ double w_m = (double)items[i].m / MAX_M;
152
+ double w_l = (double)items[i].l / MAX_L;
153
+ double cost = alpha * w_m + (1.0 - alpha) * w_l;
154
+ if (cost < 1e-15) cost = 1e-15;
155
+ density[i] = { (double)items[i].v / cost, i };
156
+ }
157
+
158
+ // Sort items by calculated density
159
+ sort(density.rbegin(), density.rend());
160
+
161
+ vector<int> order;
162
+ for(auto p : density) order.push_back(p.second);
163
+
164
+ // Construct initial greedy solution
165
+ Solution currSol(N);
166
+ fillGreedy(currSol, order);
167
+
168
+ // Local Search: "Remove-1-and-Fill" Strategy
169
+ // Try to escape local optima by removing one item and refilling greedily
170
+ bool improved = true;
171
+ while (improved) {
172
+ improved = false;
173
+ Solution localBest = currSol;
174
+
175
+ for (int i = 0; i < N; ++i) {
176
+ if (currSol.counts[i] > 0) {
177
+ Solution temp = currSol;
178
+ // Remove 1 unit of item i
179
+ temp.counts[i]--;
180
+ temp.total_v -= items[i].v;
181
+ temp.total_m -= items[i].m;
182
+ temp.total_l -= items[i].l;
183
+
184
+ // Try to fill remaining space
185
+ fillGreedy(temp, order);
186
+
187
+ if (temp.total_v > localBest.total_v) {
188
+ localBest = temp;
189
+ improved = true;
190
+ }
191
+ }
192
+ }
193
+ if (improved) currSol = localBest;
194
+ }
195
+
196
+ if (currSol.total_v > bestSol.total_v) {
197
+ bestSol = currSol;
198
+ }
199
+ }
200
+
201
+ // Output result in JSON format
202
+ cout << "{";
203
+ map<string, int> outMap;
204
+ for(int i=0; i<N; ++i) {
205
+ outMap[items[i].name] = bestSol.counts[i];
206
+ }
207
+
208
+ bool first = true;
209
+ for (auto const& [key, val] : outMap) {
210
+ if (!first) cout << ",";
211
+ cout << "\n \"" << key << "\": " << val;
212
+ first = false;
213
+ }
214
+ cout << "\n}" << endl;
215
+
216
+ return 0;
217
+ }
docker_space/frontier_cs_1/examples/gemini3pro_1.cpp ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <vector>
3
+ #include <string>
4
+ #include <algorithm>
5
+ #include <sstream>
6
+ #include <random>
7
+ #include <chrono>
8
+
9
+ using namespace std;
10
+
11
+ // Problem Constants
12
+ const long long MAX_MASS_MG = 20000000;
13
+ const long long MAX_VOL_UL = 25000000;
14
+
15
+ struct Item {
16
+ string name;
17
+ int id;
18
+ long long q;
19
+ long long v;
20
+ long long m;
21
+ long long l;
22
+ };
23
+
24
+ // Solution state
25
+ struct Solution {
26
+ vector<long long> counts;
27
+ long long current_m;
28
+ long long current_l;
29
+ long long current_v;
30
+
31
+ Solution(int n) : counts(n, 0), current_m(0), current_l(0), current_v(0) {}
32
+ };
33
+
34
+ int main() {
35
+ // Optimize I/O operations
36
+ ios_base::sync_with_stdio(false);
37
+ cin.tie(NULL);
38
+
39
+ // Parse Input
40
+ // Reading all stdin into a string
41
+ string raw_input;
42
+ string line;
43
+ while(getline(cin, line)) {
44
+ raw_input += line + " ";
45
+ }
46
+
47
+ // Replace JSON delimiters with spaces to simplify parsing
48
+ for(char &c : raw_input) {
49
+ if (c == '{' || c == '}' || c == '[' || c == ']' || c == ',' || c == '"' || c == ':') {
50
+ c = ' ';
51
+ }
52
+ }
53
+
54
+ stringstream ss(raw_input);
55
+ string key;
56
+ vector<Item> items;
57
+ int id_gen = 0;
58
+
59
+ // Parse loop
60
+ while(ss >> key) {
61
+ Item item;
62
+ item.name = key;
63
+ item.id = id_gen++;
64
+ if (!(ss >> item.q >> item.v >> item.m >> item.l)) break;
65
+ items.push_back(item);
66
+ }
67
+
68
+ int N = items.size();
69
+ if (N == 0) {
70
+ cout << "{}" << endl;
71
+ return 0;
72
+ }
73
+
74
+ // Random engine
75
+ mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
76
+
77
+ // Track best solution
78
+ long long best_v = -1;
79
+ vector<long long> best_counts(N, 0);
80
+
81
+ // Time control
82
+ clock_t start_clock = clock();
83
+ double time_limit = 0.95; // Use slightly less than 1.0s to be safe
84
+
85
+ // Auxiliary vector for item indices
86
+ vector<int> indices(N);
87
+ for(int i=0; i<N; ++i) indices[i] = i;
88
+
89
+ // Main Optimization Loop
90
+ while (true) {
91
+ // Check time limit
92
+ if ((double)(clock() - start_clock) / CLOCKS_PER_SEC > time_limit) break;
93
+
94
+ // 1. Randomized Greedy Construction
95
+
96
+ // Generate random weights for scoring metric
97
+ uniform_real_distribution<double> dist01(0.0, 1.0);
98
+ double w_mass = dist01(rng);
99
+
100
+ // Occasionally try pure strategies
101
+ double rand_strat = dist01(rng);
102
+ if (rand_strat < 0.1) w_mass = 1.0;
103
+ else if (rand_strat < 0.2) w_mass = 0.0;
104
+
105
+ double w_vol = 1.0 - w_mass;
106
+
107
+ // Rank items
108
+ vector<pair<double, int>> ranked(N);
109
+ for(int i=0; i<N; ++i) {
110
+ double cost = 0;
111
+ // Normalized cost
112
+ if (MAX_MASS_MG > 0) cost += w_mass * ((double)items[i].m / MAX_MASS_MG);
113
+ if (MAX_VOL_UL > 0) cost += w_vol * ((double)items[i].l / MAX_VOL_UL);
114
+
115
+ if (cost < 1e-15) cost = 1e-15;
116
+
117
+ double score = (double)items[i].v / cost;
118
+ // Add multiplicative noise to score to explore local variations
119
+ double noise = dist01(rng) * 0.4 + 0.8; // Range [0.8, 1.2]
120
+ ranked[i] = {score * noise, i};
121
+ }
122
+
123
+ sort(ranked.rbegin(), ranked.rend());
124
+
125
+ // Fill greedily
126
+ Solution sol(N);
127
+ for(auto& p : ranked) {
128
+ int idx = p.second;
129
+ long long rem_m = MAX_MASS_MG - sol.current_m;
130
+ long long rem_l = MAX_VOL_UL - sol.current_l;
131
+
132
+ long long count = items[idx].q;
133
+ if (items[idx].m > 0) count = min(count, rem_m / items[idx].m);
134
+ if (items[idx].l > 0) count = min(count, rem_l / items[idx].l);
135
+
136
+ sol.counts[idx] = count;
137
+ sol.current_m += count * items[idx].m;
138
+ sol.current_l += count * items[idx].l;
139
+ sol.current_v += count * items[idx].v;
140
+ }
141
+
142
+ // 2. Local Search
143
+
144
+ // Phase A: Fill Gaps
145
+ // Try to add any item that fits
146
+ shuffle(indices.begin(), indices.end(), rng);
147
+ bool changed = true;
148
+ while(changed) {
149
+ changed = false;
150
+ for(int idx : indices) {
151
+ if (sol.counts[idx] < items[idx].q) {
152
+ long long rem_m = MAX_MASS_MG - sol.current_m;
153
+ long long rem_l = MAX_VOL_UL - sol.current_l;
154
+
155
+ long long can_add = items[idx].q - sol.counts[idx];
156
+ if (items[idx].m > 0) can_add = min(can_add, rem_m / items[idx].m);
157
+ if (items[idx].l > 0) can_add = min(can_add, rem_l / items[idx].l);
158
+
159
+ if (can_add > 0) {
160
+ sol.counts[idx] += can_add;
161
+ sol.current_m += can_add * items[idx].m;
162
+ sol.current_l += can_add * items[idx].l;
163
+ sol.current_v += can_add * items[idx].v;
164
+ changed = true;
165
+ }
166
+ }
167
+ }
168
+ }
169
+
170
+ // Phase B: Pairwise Exchange
171
+ // Try to force add item j by removing items of type i
172
+ bool improved = true;
173
+ while(improved) {
174
+ improved = false;
175
+ // Check time inside local search to prevent timeout in edge cases
176
+ if ((double)(clock() - start_clock) / CLOCKS_PER_SEC > time_limit) break;
177
+
178
+ for(int i : indices) { // Candidate to remove
179
+ if (sol.counts[i] == 0) continue;
180
+ for(int j : indices) { // Candidate to add
181
+ if (i == j || sol.counts[j] >= items[j].q) continue;
182
+
183
+ // We want to add at least 1 item of j.
184
+ long long rem_m = MAX_MASS_MG - sol.current_m;
185
+ long long rem_l = MAX_VOL_UL - sol.current_l;
186
+
187
+ long long need_m = (items[j].m > rem_m) ? (items[j].m - rem_m) : 0;
188
+ long long need_l = (items[j].l > rem_l) ? (items[j].l - rem_l) : 0;
189
+
190
+ if (need_m == 0 && need_l == 0) {
191
+ // Fits without removal (should be handled by gap fill, but safe to have)
192
+ long long take = 1;
193
+ sol.counts[j] += take;
194
+ sol.current_m += items[j].m;
195
+ sol.current_l += items[j].l;
196
+ sol.current_v += items[j].v;
197
+ improved = true;
198
+ goto next_iter;
199
+ }
200
+
201
+ // Calculate minimum items of i to remove to fit 1 j
202
+ long long remove_i = 0;
203
+ bool possible = true;
204
+
205
+ if (need_m > 0) {
206
+ if (items[i].m == 0) { possible = false; }
207
+ else remove_i = max(remove_i, (need_m + items[i].m - 1) / items[i].m);
208
+ }
209
+ if (possible && need_l > 0) {
210
+ if (items[i].l == 0) { possible = false; }
211
+ else remove_i = max(remove_i, (need_l + items[i].l - 1) / items[i].l);
212
+ }
213
+
214
+ if (!possible || remove_i > sol.counts[i]) continue;
215
+
216
+ // Tentative Swap
217
+ // Remove k items of i
218
+ long long old_count_i = sol.counts[i];
219
+ long long old_count_j = sol.counts[j];
220
+ long long old_m = sol.current_m;
221
+ long long old_l = sol.current_l;
222
+ long long old_v = sol.current_v;
223
+
224
+ sol.counts[i] -= remove_i;
225
+ sol.current_m -= remove_i * items[i].m;
226
+ sol.current_l -= remove_i * items[i].l;
227
+ sol.current_v -= remove_i * items[i].v;
228
+
229
+ // Fill with j as much as possible
230
+ long long can_add_j = items[j].q - sol.counts[j];
231
+ long long room_m = MAX_MASS_MG - sol.current_m;
232
+ long long room_l = MAX_VOL_UL - sol.current_l;
233
+
234
+ if (items[j].m > 0) can_add_j = min(can_add_j, room_m / items[j].m);
235
+ if (items[j].l > 0) can_add_j = min(can_add_j, room_l / items[j].l);
236
+
237
+ if (can_add_j < 1) {
238
+ // Should not happen if logic is correct, but sanity check
239
+ // Revert
240
+ sol.counts[i] = old_count_i;
241
+ sol.counts[j] = old_count_j;
242
+ sol.current_m = old_m;
243
+ sol.current_l = old_l;
244
+ sol.current_v = old_v;
245
+ continue;
246
+ }
247
+
248
+ sol.counts[j] += can_add_j;
249
+ sol.current_m += can_add_j * items[j].m;
250
+ sol.current_l += can_add_j * items[j].l;
251
+ sol.current_v += can_add_j * items[j].v;
252
+
253
+ // Check improvement
254
+ if (sol.current_v > old_v) {
255
+ improved = true;
256
+ goto next_iter;
257
+ } else {
258
+ // Revert
259
+ sol.counts[i] = old_count_i;
260
+ sol.counts[j] = old_count_j;
261
+ sol.current_m = old_m;
262
+ sol.current_l = old_l;
263
+ sol.current_v = old_v;
264
+ }
265
+ }
266
+ }
267
+ next_iter:;
268
+ }
269
+
270
+ // Update Global Best
271
+ if (sol.current_v > best_v) {
272
+ best_v = sol.current_v;
273
+ best_counts = sol.counts;
274
+ }
275
+ }
276
+
277
+ // Output Result
278
+ cout << "{" << endl;
279
+ for(int i=0; i<N; ++i) {
280
+ cout << " \"" << items[i].name << "\": " << best_counts[i];
281
+ if (i < N - 1) cout << ",";
282
+ cout << endl;
283
+ }
284
+ cout << "}" << endl;
285
+
286
+ return 0;
287
+ }
docker_space/frontier_cs_1/examples/gemini3pro_2.cpp ADDED
@@ -0,0 +1,288 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <vector>
3
+ #include <string>
4
+ #include <algorithm>
5
+ #include <ctime>
6
+ #include <cstdlib>
7
+ #include <random>
8
+ #include <chrono>
9
+
10
+ using namespace std;
11
+
12
+ const long long MAX_M = 20000000; // 20 kg in mg
13
+ const long long MAX_L = 25000000; // 25 L in uL
14
+
15
+ struct Item {
16
+ string name;
17
+ int id;
18
+ int q;
19
+ long long v, m, l;
20
+ };
21
+
22
+ struct Solution {
23
+ vector<int> counts;
24
+ long long total_v;
25
+ long long total_m;
26
+ long long total_l;
27
+
28
+ Solution(int n) : counts(n, 0), total_v(0), total_m(0), total_l(0) {}
29
+
30
+ // Try to add one unit of item idx
31
+ bool add(int idx, const vector<Item>& items) {
32
+ if (counts[idx] >= items[idx].q) return false;
33
+ if (total_m + items[idx].m > MAX_M) return false;
34
+ if (total_l + items[idx].l > MAX_L) return false;
35
+ counts[idx]++;
36
+ total_v += items[idx].v;
37
+ total_m += items[idx].m;
38
+ total_l += items[idx].l;
39
+ return true;
40
+ }
41
+
42
+ // Try to remove one unit of item idx
43
+ bool remove(int idx, const vector<Item>& items) {
44
+ if (counts[idx] <= 0) return false;
45
+ counts[idx]--;
46
+ total_v -= items[idx].v;
47
+ total_m -= items[idx].m;
48
+ total_l -= items[idx].l;
49
+ return true;
50
+ }
51
+
52
+ // Fill remaining space with items in order of p
53
+ void fill(const vector<Item>& items, const vector<int>& p) {
54
+ for (int idx : p) {
55
+ long long rem_m = MAX_M - total_m;
56
+ long long rem_l = MAX_L - total_l;
57
+
58
+ long long count_by_m = (items[idx].m == 0) ? items[idx].q : rem_m / items[idx].m;
59
+ long long count_by_l = (items[idx].l == 0) ? items[idx].q : rem_l / items[idx].l;
60
+
61
+ int take = (int)min((long long)(items[idx].q - counts[idx]), min(count_by_m, count_by_l));
62
+
63
+ if (take > 0) {
64
+ counts[idx] += take;
65
+ total_v += (long long)take * items[idx].v;
66
+ total_m += (long long)take * items[idx].m;
67
+ total_l += (long long)take * items[idx].l;
68
+ }
69
+ }
70
+ }
71
+ };
72
+
73
+ vector<Item> items;
74
+ int N;
75
+
76
+ void parse_input() {
77
+ string s, line;
78
+ while (getline(cin, line)) s += line;
79
+
80
+ // Remove whitespace
81
+ string clean;
82
+ clean.reserve(s.size());
83
+ for (char c : s) if (!isspace(c)) clean += c;
84
+ s = clean;
85
+
86
+ size_t pos = 1; // skip '{'
87
+ while (pos < s.length() && s[pos] != '}') {
88
+ if (s[pos] == ',') { pos++; continue; }
89
+ if (s[pos] == '"') {
90
+ size_t end_quote = s.find('"', pos + 1);
91
+ string key = s.substr(pos + 1, end_quote - pos - 1);
92
+ pos = end_quote + 1;
93
+ if (s[pos] == ':') pos++;
94
+ if (s[pos] == '[') pos++;
95
+
96
+ Item item;
97
+ item.name = key;
98
+ item.id = items.size();
99
+
100
+ for (int i = 0; i < 4; ++i) {
101
+ size_t next_comma = s.find_first_of(",]", pos);
102
+ string num_str = s.substr(pos, next_comma - pos);
103
+ long long val = stoll(num_str);
104
+ if (i == 0) item.q = (int)val;
105
+ else if (i == 1) item.v = val;
106
+ else if (i == 2) item.m = val;
107
+ else if (i == 3) item.l = val;
108
+ pos = next_comma + 1;
109
+ }
110
+ items.push_back(item);
111
+ } else {
112
+ pos++;
113
+ }
114
+ }
115
+ }
116
+
117
+ int main() {
118
+ ios_base::sync_with_stdio(false);
119
+ cin.tie(NULL);
120
+
121
+ parse_input();
122
+ N = items.size();
123
+
124
+ unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
125
+ std::default_random_engine generator(seed);
126
+ std::uniform_real_distribution<double> dist(0.0, 1.0);
127
+ srand(seed);
128
+
129
+ Solution best_sol(N);
130
+
131
+ clock_t start_time = clock();
132
+ // Use 0.9 seconds to stay safe within 1s limit
133
+ double time_limit = 0.9;
134
+
135
+ auto solve_heuristic = [&](double alpha, double beta, bool rand_perturb) {
136
+ vector<int> p(N);
137
+ for(int i=0; i<N; ++i) p[i] = i;
138
+
139
+ sort(p.begin(), p.end(), [&](int a, int b) {
140
+ double wa = (double)items[a].v / (alpha * items[a].m + beta * items[a].l + 1e-9);
141
+ double wb = (double)items[b].v / (alpha * items[b].m + beta * items[b].l + 1e-9);
142
+ if (rand_perturb) {
143
+ // Slightly randomize the density to break ties or explore neighbors
144
+ wa *= (0.95 + 0.1 * dist(generator));
145
+ wb *= (0.95 + 0.1 * dist(generator));
146
+ }
147
+ return wa > wb;
148
+ });
149
+
150
+ Solution cur(N);
151
+ cur.fill(items, p);
152
+
153
+ // Local Search / Hill Climbing
154
+ bool improved = true;
155
+ while (improved) {
156
+ improved = false;
157
+
158
+ // 1. Try adding items that fit
159
+ for (int i = 0; i < N; ++i) {
160
+ if (cur.add(i, items)) {
161
+ improved = true;
162
+ while(cur.add(i, items));
163
+ }
164
+ }
165
+
166
+ // 2. Try swapping: remove 1 item, fill with others
167
+ vector<int> check_order(N);
168
+ for(int k=0; k<N; ++k) check_order[k] = k;
169
+ std::shuffle(check_order.begin(), check_order.end(), generator);
170
+
171
+ for (int i : check_order) {
172
+ if (cur.counts[i] > 0) {
173
+ cur.remove(i, items);
174
+ long long val_prev = cur.total_v + items[i].v;
175
+
176
+ // Try filling with current heuristic order p
177
+ Solution temp = cur;
178
+ temp.fill(items, p);
179
+
180
+ if (temp.total_v > val_prev) {
181
+ cur = temp;
182
+ improved = true;
183
+ break;
184
+ } else {
185
+ cur.add(i, items); // Revert
186
+ }
187
+ }
188
+ }
189
+ }
190
+
191
+ if (cur.total_v > best_sol.total_v) {
192
+ best_sol = cur;
193
+ }
194
+ };
195
+
196
+ // 1. Deterministic Sweeps
197
+ for (int i = 0; i <= 20; ++i) {
198
+ double alpha = i / 20.0;
199
+ solve_heuristic(alpha, 1.0 - alpha, false);
200
+ solve_heuristic(alpha, 1.0, false);
201
+ solve_heuristic(1.0, alpha, false);
202
+ }
203
+
204
+ // 2. Randomized Search + Iterated Greedy
205
+ while ((double)(clock() - start_time) / CLOCKS_PER_SEC < time_limit) {
206
+ // Random Weights from scratch
207
+ double alpha = dist(generator);
208
+ double beta = dist(generator);
209
+ solve_heuristic(alpha, beta, true);
210
+
211
+ // Iterated Greedy: Perturb best solution
212
+ if (best_sol.total_v > 0) {
213
+ Solution cur = best_sol;
214
+
215
+ // Remove random parts
216
+ int types_to_reduce = 1 + rand() % 4;
217
+ for(int k=0; k<types_to_reduce; ++k) {
218
+ int idx = rand() % N;
219
+ if (cur.counts[idx] > 0) {
220
+ int remove_cnt = 1 + rand() % (max(1, cur.counts[idx]/2) + 1);
221
+ for(int r=0; r<remove_cnt; ++r) cur.remove(idx, items);
222
+ }
223
+ }
224
+
225
+ // Generate random weights for refill
226
+ double a = dist(generator);
227
+ double b = dist(generator);
228
+ vector<int> p(N);
229
+ for(int i=0; i<N; ++i) p[i] = i;
230
+ sort(p.begin(), p.end(), [&](int x, int y) {
231
+ double wx = (double)items[x].v / (a * items[x].m + b * items[x].l + 1e-9);
232
+ double wy = (double)items[y].v / (a * items[y].m + b * items[y].l + 1e-9);
233
+ return wx > wy;
234
+ });
235
+
236
+ cur.fill(items, p);
237
+
238
+ // Improve
239
+ bool improved = true;
240
+ while (improved) {
241
+ improved = false;
242
+ for (int i = 0; i < N; ++i) {
243
+ if (cur.add(i, items)) {
244
+ improved = true;
245
+ while(cur.add(i, items));
246
+ }
247
+ }
248
+ vector<int> check_order(N);
249
+ for(int k=0; k<N; ++k) check_order[k] = k;
250
+ std::shuffle(check_order.begin(), check_order.end(), generator);
251
+ for (int i : check_order) {
252
+ if (cur.counts[i] > 0) {
253
+ cur.remove(i, items);
254
+ long long val_prev = cur.total_v + items[i].v;
255
+ Solution temp = cur;
256
+ temp.fill(items, p);
257
+ if (temp.total_v > val_prev) {
258
+ cur = temp;
259
+ improved = true;
260
+ break;
261
+ } else {
262
+ cur.add(i, items);
263
+ }
264
+ }
265
+ }
266
+ }
267
+ if (cur.total_v > best_sol.total_v) best_sol = cur;
268
+ }
269
+ }
270
+
271
+ // Output
272
+ vector<int> out_order(N);
273
+ for(int i=0; i<N; ++i) out_order[i] = i;
274
+ sort(out_order.begin(), out_order.end(), [&](int a, int b){
275
+ return items[a].name < items[b].name;
276
+ });
277
+
278
+ cout << "{";
279
+ for (size_t k = 0; k < out_order.size(); ++k) {
280
+ int idx = out_order[k];
281
+ cout << "\n \"" << items[idx].name << "\": " << best_sol.counts[idx];
282
+ if (k < out_order.size() - 1) cout << ",";
283
+ else cout << "\n";
284
+ }
285
+ cout << "}" << endl;
286
+
287
+ return 0;
288
+ }
docker_space/frontier_cs_1/examples/gemini3pro_3.cpp ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <vector>
3
+ #include <string>
4
+ #include <algorithm>
5
+ #include <map>
6
+ #include <chrono>
7
+ #include <random>
8
+ #include <iomanip>
9
+
10
+ using namespace std;
11
+
12
+ // Problem Constants
13
+ const long long MAX_MASS = 20000000; // 20 kg in mg
14
+ const long long MAX_VOL = 25000000; // 25 L in uL
15
+
16
+ struct Item {
17
+ string name;
18
+ int id;
19
+ int q;
20
+ long long v;
21
+ long long m;
22
+ long long l;
23
+ };
24
+
25
+ // Global variables
26
+ vector<Item> items;
27
+ vector<string> keys_order;
28
+ map<string, int> name_to_id;
29
+ int N;
30
+
31
+ // Solution State
32
+ vector<int> best_counts;
33
+ long long best_total_value = -1;
34
+
35
+ void parse_input() {
36
+ char c;
37
+ // Skip initial whitespace and opening brace if present
38
+ // The JSON input starts with {
39
+
40
+ while (cin >> c) {
41
+ if (c == '"') {
42
+ string key = "";
43
+ // Read key until closing quote
44
+ while (cin.get(c) && c != '"') {
45
+ key += c;
46
+ }
47
+
48
+ // Key found. Expect : then [
49
+ while (cin >> c && c != '[');
50
+
51
+ // Read array values
52
+ long long q, v, m, l;
53
+
54
+ // Read q
55
+ cin >> q;
56
+ // Skip to comma
57
+ while (cin >> c && c != ',');
58
+
59
+ // Read v
60
+ cin >> v;
61
+ // Skip to comma
62
+ while (cin >> c && c != ',');
63
+
64
+ // Read m
65
+ cin >> m;
66
+ // Skip to comma
67
+ while (cin >> c && c != ',');
68
+
69
+ // Read l
70
+ cin >> l;
71
+ // Skip to closing bracket
72
+ while (cin >> c && c != ']');
73
+
74
+ Item item;
75
+ item.name = key;
76
+ item.q = (int)q;
77
+ item.v = v;
78
+ item.m = m;
79
+ item.l = l;
80
+ item.id = items.size();
81
+
82
+ name_to_id[key] = item.id;
83
+ keys_order.push_back(key);
84
+ items.push_back(item);
85
+ }
86
+ }
87
+ N = items.size();
88
+ best_counts.resize(N, 0);
89
+ }
90
+
91
+ // Timer
92
+ auto start_time = chrono::high_resolution_clock::now();
93
+
94
+ double get_elapsed() {
95
+ auto now = chrono::high_resolution_clock::now();
96
+ return chrono::duration<double>(now - start_time).count();
97
+ }
98
+
99
+ int main() {
100
+ // Fast IO
101
+ ios_base::sync_with_stdio(false);
102
+ cin.tie(NULL);
103
+
104
+ parse_input();
105
+
106
+ if (N == 0) {
107
+ cout << "{}" << endl;
108
+ return 0;
109
+ }
110
+
111
+ // Random number generator
112
+ mt19937 rng(1337);
113
+ uniform_real_distribution<double> dist_real(0.0, 1.0);
114
+ uniform_int_distribution<int> dist_int(0, N - 1);
115
+
116
+ // Indices for sorting
117
+ vector<int> p(N);
118
+ for(int i=0; i<N; ++i) p[i] = i;
119
+
120
+ // Temporary solution storage
121
+ vector<int> current_counts(N);
122
+
123
+ // Main optimization loop
124
+ // We run multiple iterations of randomized greedy heuristics
125
+ // Since N=12, we can run many iterations in 1 second.
126
+ while (get_elapsed() < 0.90) {
127
+
128
+ // Strategy: Randomized Weights for Greedy
129
+ // Generate random weights for mass and volume penalties
130
+ // This corresponds to exploring the dual space of the relaxed LP.
131
+ double w_m = dist_real(rng);
132
+ double w_l = dist_real(rng);
133
+
134
+ // Occasionally force extreme weights to explore boundaries
135
+ double r = dist_real(rng);
136
+ if (r < 0.05) { w_m = 1.0; w_l = 0.0; }
137
+ else if (r < 0.10) { w_m = 0.0; w_l = 1.0; }
138
+ else if (r < 0.15) { w_m = 1.0; w_l = 1.0; } // Equal weight
139
+ else if (r < 0.20) { w_m = 1.0; w_l = 0.0001; } // Nearly ignore volume
140
+ else if (r < 0.25) { w_m = 0.0001; w_l = 1.0; } // Nearly ignore mass
141
+
142
+ // Compute scores and sort
143
+ // Heuristic: Value / Weighted_Cost
144
+ // Cost is normalized by capacity to handle different units
145
+ sort(p.begin(), p.end(), [&](int i, int j) {
146
+ double cost_i = w_m * ((double)items[i].m / MAX_MASS) + w_l * ((double)items[i].l / MAX_VOL);
147
+ double cost_j = w_m * ((double)items[j].m / MAX_MASS) + w_l * ((double)items[j].l / MAX_VOL);
148
+ if (cost_i < 1e-12) cost_i = 1e-12;
149
+ if (cost_j < 1e-12) cost_j = 1e-12;
150
+ return (items[i].v / cost_i) > (items[j].v / cost_j);
151
+ });
152
+
153
+ // Current solution state
154
+ long long current_m = 0;
155
+ long long current_l = 0;
156
+ long long current_v = 0;
157
+ fill(current_counts.begin(), current_counts.end(), 0);
158
+
159
+ // Perturbation Strategy:
160
+ // Sometimes, force a random item to have a random count (Fix & Fill)
161
+ // This helps escape local optima where greedy dominates.
162
+ bool forced = false;
163
+ int force_idx = -1;
164
+
165
+ if (dist_real(rng) < 0.3) {
166
+ force_idx = dist_int(rng);
167
+ uniform_int_distribution<int> q_dist(1, items[force_idx].q);
168
+ int force_qty = q_dist(rng);
169
+
170
+ // Only apply if feasible alone
171
+ if (items[force_idx].m * (long long)force_qty <= MAX_MASS &&
172
+ items[force_idx].l * (long long)force_qty <= MAX_VOL) {
173
+ current_counts[force_idx] = force_qty;
174
+ current_m += items[force_idx].m * force_qty;
175
+ current_l += items[force_idx].l * force_qty;
176
+ current_v += items[force_idx].v * force_qty;
177
+ forced = true;
178
+ }
179
+ }
180
+
181
+ // Greedy Fill Phase
182
+ for (int i : p) {
183
+ if (forced && i == force_idx) continue;
184
+
185
+ long long rem_m = MAX_MASS - current_m;
186
+ long long rem_l = MAX_VOL - current_l;
187
+
188
+ if (rem_m < 0) rem_m = 0;
189
+ if (rem_l < 0) rem_l = 0;
190
+
191
+ int can_take_m = (items[i].m == 0) ? items[i].q : (int)(rem_m / items[i].m);
192
+ int can_take_l = (items[i].l == 0) ? items[i].q : (int)(rem_l / items[i].l);
193
+
194
+ int take = min(items[i].q, min(can_take_m, can_take_l));
195
+
196
+ // Small mutation: Occasionally take slightly less than max possible
197
+ // to leave space for other items
198
+ if (take > 0 && dist_real(rng) < 0.05) {
199
+ take = max(0, take - 1);
200
+ }
201
+
202
+ current_counts[i] = take;
203
+ current_m += (long long)take * items[i].m;
204
+ current_l += (long long)take * items[i].l;
205
+ current_v += (long long)take * items[i].v;
206
+ }
207
+
208
+ // Gap Filling Phase
209
+ // Iterate through all items again to fill any remaining space
210
+ // This is necessary because the sorted order might have skipped items
211
+ // that now fit in the small remaining space.
212
+ for (int i = 0; i < N; ++i) {
213
+ if (current_counts[i] < items[i].q) {
214
+ long long rem_m = MAX_MASS - current_m;
215
+ long long rem_l = MAX_VOL - current_l;
216
+
217
+ if (items[i].m <= rem_m && items[i].l <= rem_l) {
218
+ int can_take_m = (items[i].m == 0) ? items[i].q : (int)(rem_m / items[i].m);
219
+ int can_take_l = (items[i].l == 0) ? items[i].q : (int)(rem_l / items[i].l);
220
+ int extra = min(items[i].q - current_counts[i], min(can_take_m, can_take_l));
221
+
222
+ current_counts[i] += extra;
223
+ current_m += (long long)extra * items[i].m;
224
+ current_l += (long long)extra * items[i].l;
225
+ current_v += (long long)extra * items[i].v;
226
+ }
227
+ }
228
+ }
229
+
230
+ // Update Global Best
231
+ if (current_v > best_total_value) {
232
+ best_total_value = current_v;
233
+ best_counts = current_counts;
234
+ }
235
+ }
236
+
237
+ // Output JSON
238
+ cout << "{" << endl;
239
+ for (size_t i = 0; i < keys_order.size(); ++i) {
240
+ string key = keys_order[i];
241
+ int id = name_to_id[key];
242
+ cout << " \"" << key << "\": " << best_counts[id];
243
+ if (i < keys_order.size() - 1) {
244
+ cout << ",";
245
+ }
246
+ cout << endl;
247
+ }
248
+ cout << "}" << endl;
249
+
250
+ return 0;
251
+ }
docker_space/frontier_cs_1/examples/gemini3pro_4.cpp ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <iostream>
2
+ #include <vector>
3
+ #include <string>
4
+ #include <algorithm>
5
+ #include <map>
6
+ #include <cmath>
7
+ #include <ctime>
8
+ #include <random>
9
+ #include <climits>
10
+
11
+ using namespace std;
12
+
13
+ // Problem constants
14
+ const long long MAX_M = 20000000;
15
+ const long long MAX_L = 25000000;
16
+
17
+ struct Item {
18
+ string name;
19
+ int q;
20
+ long long v, m, l;
21
+ int original_index;
22
+ };
23
+
24
+ struct Solution {
25
+ vector<int> counts;
26
+ long long total_v;
27
+ long long total_m;
28
+ long long total_l;
29
+ };
30
+
31
+ vector<Item> items;
32
+ vector<string> key_order;
33
+ Solution best_sol;
34
+
35
+ // Parse JSON from stdin
36
+ void parse_input() {
37
+ string data;
38
+ char c;
39
+ while (cin.get(c)) data += c;
40
+
41
+ size_t n = data.size();
42
+ size_t i = 0;
43
+
44
+ while (i < n) {
45
+ // Find start of a key string
46
+ while (i < n && data[i] != '"') i++;
47
+ if (i >= n) break;
48
+ i++; // skip "
49
+
50
+ string key = "";
51
+ while (i < n && data[i] != '"') {
52
+ key += data[i];
53
+ i++;
54
+ }
55
+ i++; // skip closing "
56
+
57
+ // Search for colon to confirm it's a key
58
+ size_t temp_i = i;
59
+ while (temp_i < n && isspace(data[temp_i])) temp_i++;
60
+ if (temp_i >= n || data[temp_i] != ':') {
61
+ // Not a key-value pair we are interested in (or end of file)
62
+ i = temp_i;
63
+ continue;
64
+ }
65
+ i = temp_i + 1; // skip :
66
+
67
+ // Search for array start
68
+ while (i < n && data[i] != '[') i++;
69
+ if (i >= n) break;
70
+ i++; // skip [
71
+
72
+ // Parse 4 numbers
73
+ long long vals[4];
74
+ for (int k = 0; k < 4; ++k) {
75
+ while (i < n && !isdigit(data[i])) i++;
76
+ string num_s = "";
77
+ while (i < n && isdigit(data[i])) {
78
+ num_s += data[i];
79
+ i++;
80
+ }
81
+ if (!num_s.empty()) vals[k] = stoll(num_s);
82
+ else vals[k] = 0;
83
+ }
84
+
85
+ Item item;
86
+ item.name = key;
87
+ item.q = (int)vals[0];
88
+ item.v = vals[1];
89
+ item.m = vals[2];
90
+ item.l = vals[3];
91
+ item.original_index = items.size();
92
+
93
+ items.push_back(item);
94
+ key_order.push_back(key);
95
+
96
+ // skip until ]
97
+ while (i < n && data[i] != ']') i++;
98
+ i++;
99
+ }
100
+ }
101
+
102
+ int main() {
103
+ ios_base::sync_with_stdio(false);
104
+ cin.tie(NULL);
105
+
106
+ parse_input();
107
+
108
+ int N = items.size();
109
+ if (N == 0) {
110
+ cout << "{}" << endl;
111
+ return 0;
112
+ }
113
+
114
+ // Map name to index for easy lookup later
115
+ map<string, int> name_to_idx;
116
+ for (int i = 0; i < N; ++i) {
117
+ name_to_idx[items[i].name] = i;
118
+ }
119
+
120
+ // Initialize best solution
121
+ best_sol.counts.assign(N, 0);
122
+ best_sol.total_v = 0;
123
+ best_sol.total_m = 0;
124
+ best_sol.total_l = 0;
125
+
126
+ mt19937 rng(12345);
127
+ clock_t start_time = clock();
128
+
129
+ // Phase 1: GRASP (Greedy Randomized Adaptive Search Procedure)
130
+ // Run for 40% of allowed time
131
+ while ((double)(clock() - start_time) / CLOCKS_PER_SEC < 0.4) {
132
+ // Random alpha for linear combination of constraints
133
+ double alpha = (double)(rng() % 1001) / 1000.0;
134
+ vector<int> p(N);
135
+ for (int k = 0; k < N; ++k) p[k] = k;
136
+
137
+ // Randomized sorting based on value density
138
+ shuffle(p.begin(), p.end(), rng);
139
+ sort(p.begin(), p.end(), [&](int a, int b) {
140
+ double m_norm_a = (double)items[a].m / MAX_M;
141
+ double l_norm_a = (double)items[a].l / MAX_L;
142
+ double cost_a = alpha * m_norm_a + (1.0 - alpha) * l_norm_a;
143
+
144
+ double m_norm_b = (double)items[b].m / MAX_M;
145
+ double l_norm_b = (double)items[b].l / MAX_L;
146
+ double cost_b = alpha * m_norm_b + (1.0 - alpha) * l_norm_b;
147
+
148
+ if (cost_a <= 1e-12) return true;
149
+ if (cost_b <= 1e-12) return false;
150
+
151
+ double score_a = items[a].v / cost_a;
152
+ double score_b = items[b].v / cost_b;
153
+ return score_a > score_b;
154
+ });
155
+
156
+ Solution curr;
157
+ curr.counts.assign(N, 0);
158
+ curr.total_v = 0;
159
+ curr.total_m = 0;
160
+ curr.total_l = 0;
161
+
162
+ for (int idx : p) {
163
+ long long rem_m = MAX_M - curr.total_m;
164
+ long long rem_l = MAX_L - curr.total_l;
165
+
166
+ int can_take = items[idx].q;
167
+ if (items[idx].m > 0) can_take = min((long long)can_take, rem_m / items[idx].m);
168
+ if (items[idx].l > 0) can_take = min((long long)can_take, rem_l / items[idx].l);
169
+
170
+ if (can_take > 0) {
171
+ curr.counts[idx] = can_take;
172
+ curr.total_v += (long long)can_take * items[idx].v;
173
+ curr.total_m += (long long)can_take * items[idx].m;
174
+ curr.total_l += (long long)can_take * items[idx].l;
175
+ }
176
+ }
177
+
178
+ if (curr.total_v > best_sol.total_v) {
179
+ best_sol = curr;
180
+ }
181
+ }
182
+
183
+ // Phase 2: Local Search / Hill Climbing
184
+ // Start from best found in GRASP
185
+ Solution curr = best_sol;
186
+ vector<int> candidates;
187
+ candidates.reserve(N);
188
+
189
+ int iter = 0;
190
+ while (true) {
191
+ iter++;
192
+ // Check time every 1024 iterations
193
+ if ((iter & 1023) == 0) {
194
+ if ((double)(clock() - start_time) / CLOCKS_PER_SEC > 0.98) break;
195
+ }
196
+
197
+ Solution next_sol = curr;
198
+ int move_type = rng() % 3;
199
+
200
+ if (move_type == 0) {
201
+ // Move: Add item and Repair if needed
202
+ int idx = rng() % N;
203
+ if (next_sol.counts[idx] < items[idx].q) {
204
+ next_sol.counts[idx]++;
205
+ next_sol.total_v += items[idx].v;
206
+ next_sol.total_m += items[idx].m;
207
+ next_sol.total_l += items[idx].l;
208
+
209
+ // Repair if invalid
210
+ while (next_sol.total_m > MAX_M || next_sol.total_l > MAX_L) {
211
+ candidates.clear();
212
+ for(int k=0; k<N; ++k) if(next_sol.counts[k] > 0) candidates.push_back(k);
213
+ if(candidates.empty()) break;
214
+
215
+ int victim = candidates[rng() % candidates.size()];
216
+ next_sol.counts[victim]--;
217
+ next_sol.total_v -= items[victim].v;
218
+ next_sol.total_m -= items[victim].m;
219
+ next_sol.total_l -= items[victim].l;
220
+ }
221
+
222
+ // If valid and not worse, accept
223
+ if (next_sol.total_m <= MAX_M && next_sol.total_l <= MAX_L) {
224
+ if (next_sol.total_v >= curr.total_v) {
225
+ curr = next_sol;
226
+ if (curr.total_v > best_sol.total_v) best_sol = curr;
227
+ }
228
+ }
229
+ }
230
+ } else if (move_type == 1) {
231
+ // Move: Swap (Add i, Remove j)
232
+ int i = rng() % N;
233
+ int j = rng() % N;
234
+
235
+ if (i != j && next_sol.counts[i] < items[i].q && next_sol.counts[j] > 0) {
236
+ next_sol.counts[i]++;
237
+ next_sol.total_v += items[i].v;
238
+ next_sol.total_m += items[i].m;
239
+ next_sol.total_l += items[i].l;
240
+
241
+ next_sol.counts[j]--;
242
+ next_sol.total_v -= items[j].v;
243
+ next_sol.total_m -= items[j].m;
244
+ next_sol.total_l -= items[j].l;
245
+
246
+ // Only accept if valid and not worse
247
+ if (next_sol.total_m <= MAX_M && next_sol.total_l <= MAX_L) {
248
+ if (next_sol.total_v >= curr.total_v) {
249
+ curr = next_sol;
250
+ if (curr.total_v > best_sol.total_v) best_sol = curr;
251
+ }
252
+ }
253
+ }
254
+ } else {
255
+ // Move: Fill slack (Add only, valid check immediately)
256
+ int idx = rng() % N;
257
+ if (next_sol.counts[idx] < items[idx].q) {
258
+ if (next_sol.total_m + items[idx].m <= MAX_M &&
259
+ next_sol.total_l + items[idx].l <= MAX_L) {
260
+ next_sol.counts[idx]++;
261
+ next_sol.total_v += items[idx].v;
262
+ next_sol.total_m += items[idx].m;
263
+ next_sol.total_l += items[idx].l;
264
+
265
+ curr = next_sol;
266
+ if (curr.total_v > best_sol.total_v) best_sol = curr;
267
+ }
268
+ }
269
+ }
270
+ }
271
+
272
+ // Output JSON
273
+ cout << "{" << endl;
274
+ for (size_t i = 0; i < key_order.size(); ++i) {
275
+ string key = key_order[i];
276
+ int idx = name_to_idx[key];
277
+ cout << " \"" << key << "\": " << best_sol.counts[idx];
278
+ if (i < key_order.size() - 1) cout << ",";
279
+ cout << endl;
280
+ }
281
+ cout << "}" << endl;
282
+
283
+ return 0;
284
+ }
docker_space/frontier_cs_1/examples/gpt5.1.cpp ADDED
@@ -0,0 +1,334 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <bits/stdc++.h>
2
+ using namespace std;
3
+
4
+ using ll = long long;
5
+
6
+ struct Cat {
7
+ string name;
8
+ ll q, v, m, l;
9
+ };
10
+
11
+ struct Package {
12
+ int type;
13
+ int cnt;
14
+ ll value;
15
+ int sm, sl;
16
+ };
17
+
18
+ struct Solution {
19
+ vector<ll> cnts;
20
+ ll val;
21
+ ll mass;
22
+ ll vol;
23
+ };
24
+
25
+ static const ll MAX_MASS = 20LL * 1000000LL; // 20 kg in mg
26
+ static const ll MAX_VOL = 25LL * 1000000LL; // 25 L in uL
27
+
28
+ string inputStr;
29
+ size_t posPtr = 0;
30
+
31
+ void skipWS() {
32
+ while (posPtr < inputStr.size() && isspace((unsigned char)inputStr[posPtr])) posPtr++;
33
+ }
34
+
35
+ ll parseLL() {
36
+ skipWS();
37
+ int sign = 1;
38
+ if (posPtr < inputStr.size() && (inputStr[posPtr] == '-' || inputStr[posPtr] == '+')) {
39
+ if (inputStr[posPtr] == '-') sign = -1;
40
+ posPtr++;
41
+ }
42
+ ll val = 0;
43
+ while (posPtr < inputStr.size() && isdigit((unsigned char)inputStr[posPtr])) {
44
+ val = val * 10 + (inputStr[posPtr] - '0');
45
+ posPtr++;
46
+ }
47
+ return sign * val;
48
+ }
49
+
50
+ vector<Cat> parseInput() {
51
+ vector<Cat> cats;
52
+ skipWS();
53
+ if (posPtr < inputStr.size() && inputStr[posPtr] == '{') posPtr++;
54
+ while (true) {
55
+ skipWS();
56
+ if (posPtr >= inputStr.size()) break;
57
+ if (inputStr[posPtr] == '}') {
58
+ posPtr++;
59
+ break;
60
+ }
61
+ // parse key
62
+ if (inputStr[posPtr] != '"') break;
63
+ posPtr++;
64
+ size_t start = posPtr;
65
+ while (posPtr < inputStr.size() && inputStr[posPtr] != '"') posPtr++;
66
+ string key = inputStr.substr(start, posPtr - start);
67
+ if (posPtr < inputStr.size() && inputStr[posPtr] == '"') posPtr++;
68
+ skipWS();
69
+ if (posPtr < inputStr.size() && inputStr[posPtr] == ':') posPtr++;
70
+ skipWS();
71
+ if (posPtr < inputStr.size() && inputStr[posPtr] == '[') posPtr++;
72
+
73
+ ll q = parseLL();
74
+ skipWS();
75
+ if (posPtr < inputStr.size() && inputStr[posPtr] == ',') posPtr++;
76
+ ll v = parseLL();
77
+ skipWS();
78
+ if (posPtr < inputStr.size() && inputStr[posPtr] == ',') posPtr++;
79
+ ll m = parseLL();
80
+ skipWS();
81
+ if (posPtr < inputStr.size() && inputStr[posPtr] == ',') posPtr++;
82
+ ll l = parseLL();
83
+ skipWS();
84
+ if (posPtr < inputStr.size() && inputStr[posPtr] == ']') posPtr++;
85
+ skipWS();
86
+ if (posPtr < inputStr.size() && inputStr[posPtr] == ',') posPtr++;
87
+
88
+ Cat c;
89
+ c.name = key;
90
+ c.q = q;
91
+ c.v = v;
92
+ c.m = m;
93
+ c.l = l;
94
+ cats.push_back(c);
95
+ }
96
+ return cats;
97
+ }
98
+
99
+ Solution solveDP(const vector<Cat>& cats) {
100
+ int n = (int)cats.size();
101
+ const int TARGET = 200;
102
+
103
+ ll M = MAX_MASS;
104
+ ll L = MAX_VOL;
105
+
106
+ ll fMass = max(1LL, (M + TARGET - 1) / TARGET); // ceil(M/TARGET)
107
+ ll fVol = max(1LL, (L + TARGET - 1) / TARGET);
108
+
109
+ int sM = (int)(M / fMass); // <= TARGET
110
+ int sL = (int)(L / fVol); // <= TARGET
111
+
112
+ int width = sL + 1;
113
+ int S = (sM + 1) * (sL + 1);
114
+
115
+ vector<Package> pkgs;
116
+ pkgs.reserve(n * 16);
117
+
118
+ for (int i = 0; i < n; ++i) {
119
+ ll q = cats[i].q;
120
+ ll remain = q;
121
+ ll k = 1;
122
+ while (remain > 0) {
123
+ ll cnt = min(k, remain);
124
+ ll mass = cats[i].m * cnt;
125
+ ll vol = cats[i].l * cnt;
126
+ if (mass <= M && vol <= L) {
127
+ int sm = (int)((mass + fMass - 1) / fMass);
128
+ int sl = (int)((vol + fVol - 1) / fVol);
129
+ if (sm <= sM && sl <= sL) {
130
+ Package p;
131
+ p.type = i;
132
+ p.cnt = (int)cnt;
133
+ p.value = cats[i].v * cnt;
134
+ p.sm = sm;
135
+ p.sl = sl;
136
+ pkgs.push_back(p);
137
+ }
138
+ }
139
+ remain -= cnt;
140
+ k <<= 1;
141
+ }
142
+ }
143
+
144
+ int P = (int)pkgs.size();
145
+ const ll NEG_INF = (ll)-4e18;
146
+
147
+ vector<ll> dp(S, NEG_INF);
148
+ dp[0] = 0;
149
+ vector<unsigned char> choose((size_t)P * (size_t)S, 0);
150
+
151
+ for (int p = 0; p < P; ++p) {
152
+ int wM = pkgs[p].sm;
153
+ int wL = pkgs[p].sl;
154
+ ll val = pkgs[p].value;
155
+ for (int m = sM; m >= wM; --m) {
156
+ int baseRow = m * width;
157
+ int prevRow = (m - wM) * width;
158
+ for (int l = sL; l >= wL; --l) {
159
+ int idx = baseRow + l;
160
+ int prev = prevRow + (l - wL);
161
+ ll prevVal = dp[prev];
162
+ if (prevVal == NEG_INF) continue;
163
+ ll cand = prevVal + val;
164
+ if (cand > dp[idx]) {
165
+ dp[idx] = cand;
166
+ choose[(size_t)p * (size_t)S + (size_t)idx] = 1;
167
+ }
168
+ }
169
+ }
170
+ }
171
+
172
+ ll bestVal = 0;
173
+ int bestIdx = 0;
174
+ for (int idx = 0; idx < S; ++idx) {
175
+ if (dp[idx] > bestVal) {
176
+ bestVal = dp[idx];
177
+ bestIdx = idx;
178
+ }
179
+ }
180
+
181
+ vector<ll> cnts(n, 0);
182
+ int curM = bestIdx / width;
183
+ int curL = bestIdx % width;
184
+
185
+ for (int p = P - 1; p >= 0; --p) {
186
+ int idx = curM * width + curL;
187
+ if (choose[(size_t)p * (size_t)S + (size_t)idx]) {
188
+ cnts[pkgs[p].type] += pkgs[p].cnt;
189
+ curM -= pkgs[p].sm;
190
+ curL -= pkgs[p].sl;
191
+ }
192
+ }
193
+
194
+ Solution sol;
195
+ sol.cnts = cnts;
196
+ sol.mass = 0;
197
+ sol.vol = 0;
198
+ sol.val = 0;
199
+ for (int i = 0; i < n; ++i) {
200
+ sol.mass += sol.cnts[i] * cats[i].m;
201
+ sol.vol += sol.cnts[i] * cats[i].l;
202
+ sol.val += sol.cnts[i] * cats[i].v;
203
+ }
204
+ // Feasibility should hold by construction.
205
+ if (sol.mass > M || sol.vol > L) {
206
+ // Safety fallback: zero solution
207
+ sol.cnts.assign(n, 0);
208
+ sol.mass = sol.vol = sol.val = 0;
209
+ }
210
+ return sol;
211
+ }
212
+
213
+ Solution greedyFill(const vector<Cat>& cats,
214
+ const vector<ll>& baseCnt,
215
+ ll baseMass, ll baseVol, ll baseVal,
216
+ int mode) {
217
+ int n = (int)cats.size();
218
+ Solution sol;
219
+ sol.cnts = baseCnt;
220
+ sol.mass = baseMass;
221
+ sol.vol = baseVol;
222
+ sol.val = baseVal;
223
+
224
+ if (sol.mass > MAX_MASS || sol.vol > MAX_VOL) {
225
+ // invalid base; return as is
226
+ return sol;
227
+ }
228
+
229
+ vector<ll> remaining(n);
230
+ for (int i = 0; i < n; ++i) {
231
+ ll rem = cats[i].q - baseCnt[i];
232
+ if (rem < 0) rem = 0;
233
+ remaining[i] = rem;
234
+ }
235
+
236
+ vector<int> idxs;
237
+ idxs.reserve(n);
238
+ for (int i = 0; i < n; ++i) {
239
+ if (remaining[i] > 0) idxs.push_back(i);
240
+ }
241
+ if (idxs.empty()) return sol;
242
+
243
+ vector<double> score(n, 0.0);
244
+ for (int i : idxs) {
245
+ double s = 0.0;
246
+ double d1 = (double)cats[i].m / (double)MAX_MASS;
247
+ double d2 = (double)cats[i].l / (double)MAX_VOL;
248
+ switch (mode) {
249
+ case 0: // normalized sum
250
+ s = (double)cats[i].v / (d1 + d2);
251
+ break;
252
+ case 1: // value per mass
253
+ s = (double)cats[i].v / (double)cats[i].m;
254
+ break;
255
+ case 2: // value per volume
256
+ s = (double)cats[i].v / (double)cats[i].l;
257
+ break;
258
+ case 3: { // value per max normalized
259
+ double d = max(d1, d2);
260
+ s = (double)cats[i].v / d;
261
+ break;
262
+ }
263
+ default:
264
+ s = (double)cats[i].v / (d1 + d2);
265
+ break;
266
+ }
267
+ score[i] = s;
268
+ }
269
+
270
+ sort(idxs.begin(), idxs.end(), [&](int a, int b) {
271
+ if (score[a] == score[b]) return cats[a].v > cats[b].v;
272
+ return score[a] > score[b];
273
+ });
274
+
275
+ for (int i : idxs) {
276
+ if (remaining[i] <= 0) continue;
277
+ if (sol.mass >= MAX_MASS || sol.vol >= MAX_VOL) break;
278
+ ll maxByMass = (cats[i].m > 0) ? ( (MAX_MASS - sol.mass) / cats[i].m ) : remaining[i];
279
+ ll maxByVol = (cats[i].l > 0) ? ( (MAX_VOL - sol.vol ) / cats[i].l ) : remaining[i];
280
+ ll canTake = min(remaining[i], min(maxByMass, maxByVol));
281
+ if (canTake <= 0) continue;
282
+ sol.cnts[i] += canTake;
283
+ sol.mass += canTake * cats[i].m;
284
+ sol.vol += canTake * cats[i].l;
285
+ sol.val += canTake * cats[i].v;
286
+ }
287
+
288
+ return sol;
289
+ }
290
+
291
+ int main() {
292
+ ios::sync_with_stdio(false);
293
+ cin.tie(nullptr);
294
+
295
+ inputStr.assign((istreambuf_iterator<char>(cin)), istreambuf_iterator<char>());
296
+ vector<Cat> cats = parseInput();
297
+ int n = (int)cats.size();
298
+
299
+ vector<ll> emptyCnt(n, 0);
300
+
301
+ Solution best;
302
+ best.cnts = emptyCnt;
303
+ best.mass = 0;
304
+ best.vol = 0;
305
+ best.val = 0;
306
+
307
+ // Greedy from empty with various heuristics
308
+ for (int mode = 0; mode <= 3; ++mode) {
309
+ Solution cand = greedyFill(cats, emptyCnt, 0, 0, 0, mode);
310
+ if (cand.mass <= MAX_MASS && cand.vol <= MAX_VOL && cand.val > best.val) {
311
+ best = cand;
312
+ }
313
+ }
314
+
315
+ // DP-based solution + greedy refinements
316
+ Solution dpSol = solveDP(cats);
317
+ for (int mode = 0; mode <= 3; ++mode) {
318
+ Solution cand = greedyFill(cats, dpSol.cnts, dpSol.mass, dpSol.vol, dpSol.val, mode);
319
+ if (cand.mass <= MAX_MASS && cand.vol <= MAX_VOL && cand.val > best.val) {
320
+ best = cand;
321
+ }
322
+ }
323
+
324
+ // Output JSON with same key order
325
+ cout << "{\n";
326
+ for (int i = 0; i < n; ++i) {
327
+ cout << " \"" << cats[i].name << "\": " << best.cnts[i];
328
+ if (i + 1 < n) cout << ",\n";
329
+ else cout << "\n";
330
+ }
331
+ cout << "}\n";
332
+
333
+ return 0;
334
+ }
docker_space/frontier_cs_1/examples/gpt5.1_1.cpp ADDED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <bits/stdc++.h>
2
+ using namespace std;
3
+
4
+ int main() {
5
+ ios::sync_with_stdio(false);
6
+ cin.tie(nullptr);
7
+
8
+ // Read entire input
9
+ string s((istreambuf_iterator<char>(cin)), istreambuf_iterator<char>());
10
+ size_t pos = 0;
11
+
12
+ auto skipWS = [&]() {
13
+ while (pos < s.size() && isspace((unsigned char)s[pos])) ++pos;
14
+ };
15
+
16
+ auto parseString = [&]() -> string {
17
+ skipWS();
18
+ if (pos >= s.size() || s[pos] != '"') return "";
19
+ ++pos;
20
+ size_t start = pos;
21
+ while (pos < s.size() && s[pos] != '"') ++pos;
22
+ string res = s.substr(start, pos - start);
23
+ if (pos < s.size() && s[pos] == '"') ++pos;
24
+ return res;
25
+ };
26
+
27
+ auto parseLongLong = [&]() -> long long {
28
+ skipWS();
29
+ int sign = 1;
30
+ if (pos < s.size() && s[pos] == '-') {
31
+ sign = -1;
32
+ ++pos;
33
+ }
34
+ long long val = 0;
35
+ while (pos < s.size() && isdigit((unsigned char)s[pos])) {
36
+ val = val * 10 + (s[pos] - '0');
37
+ ++pos;
38
+ }
39
+ return sign * val;
40
+ };
41
+
42
+ skipWS();
43
+ if (pos < s.size() && s[pos] == '{') ++pos;
44
+
45
+ vector<string> names;
46
+ vector<long long> q, v, m, l;
47
+
48
+ while (true) {
49
+ skipWS();
50
+ if (pos >= s.size()) break;
51
+ if (s[pos] == '}') {
52
+ ++pos;
53
+ break;
54
+ }
55
+
56
+ string name = parseString();
57
+ if (name.empty()) break;
58
+
59
+ // Skip until '['
60
+ while (pos < s.size() && s[pos] != '[') ++pos;
61
+ if (pos < s.size() && s[pos] == '[') ++pos;
62
+
63
+ long long nums[4];
64
+ for (int i = 0; i < 4; ++i) {
65
+ nums[i] = parseLongLong();
66
+ skipWS();
67
+ if (i < 3 && pos < s.size() && s[pos] == ',') ++pos;
68
+ }
69
+
70
+ // Skip until ']'
71
+ while (pos < s.size() && s[pos] != ']') ++pos;
72
+ if (pos < s.size() && s[pos] == ']') ++pos;
73
+
74
+ skipWS();
75
+ if (pos < s.size() && s[pos] == ',') ++pos;
76
+
77
+ names.push_back(name);
78
+ q.push_back(nums[0]);
79
+ v.push_back(nums[1]);
80
+ m.push_back(nums[2]);
81
+ l.push_back(nums[3]);
82
+ }
83
+
84
+ int n = (int)names.size();
85
+ if (n == 0) {
86
+ cout << "{}\n";
87
+ return 0;
88
+ }
89
+
90
+ const long long M_CAP = 20'000'000LL;
91
+ const long long L_CAP = 25'000'000LL;
92
+
93
+ vector<long long> bestX(n, 0);
94
+ long long bestVal = 0;
95
+
96
+ auto greedyFromOrder = [&](const vector<int> &order) {
97
+ vector<long long> x(n, 0);
98
+ long long usedM = 0;
99
+ long long usedL = 0;
100
+ long long totalVal = 0;
101
+ for (int idx : order) {
102
+ if (usedM >= M_CAP || usedL >= L_CAP) break;
103
+ long long remM = M_CAP - usedM;
104
+ long long remL = L_CAP - usedL;
105
+ long long maxByM = remM / m[idx];
106
+ long long maxByL = remL / l[idx];
107
+ long long canTake = std::min<long long>({q[idx], maxByM, maxByL});
108
+ if (canTake <= 0) continue;
109
+ x[idx] = canTake;
110
+ usedM += canTake * m[idx];
111
+ usedL += canTake * l[idx];
112
+ totalVal += canTake * v[idx];
113
+ }
114
+ if (totalVal > bestVal) {
115
+ bestVal = totalVal;
116
+ bestX = std::move(x);
117
+ }
118
+ };
119
+
120
+ double M_cap_d = (double)M_CAP;
121
+ double L_cap_d = (double)L_CAP;
122
+ vector<double> mNorm(n), lNorm(n);
123
+ for (int i = 0; i < n; ++i) {
124
+ mNorm[i] = (double)m[i] / M_cap_d;
125
+ lNorm[i] = (double)l[i] / L_cap_d;
126
+ }
127
+
128
+ auto runHeuristic = [&](auto getDensity) {
129
+ struct Pair {
130
+ double d;
131
+ int idx;
132
+ };
133
+ vector<Pair> arr;
134
+ arr.reserve(n);
135
+ for (int i = 0; i < n; ++i) {
136
+ double d = getDensity(i);
137
+ if (!std::isfinite(d)) d = -1e300;
138
+ arr.push_back({d, i});
139
+ }
140
+ sort(arr.begin(), arr.end(), [](const Pair &a, const Pair &b) {
141
+ return a.d > b.d;
142
+ });
143
+ vector<int> order;
144
+ order.reserve(n);
145
+ for (auto &p : arr) order.push_back(p.idx);
146
+ greedyFromOrder(order);
147
+ };
148
+
149
+ // Basic heuristics
150
+ runHeuristic([&](int i) { return (double)v[i] / (double)m[i]; }); // value per mass
151
+ runHeuristic([&](int i) { return (double)v[i] / (double)l[i]; }); // value per volume
152
+ runHeuristic([&](int i) { return (double)v[i]; }); // raw value
153
+ runHeuristic([&](int i) { return (double)v[i] / (mNorm[i] + lNorm[i]); }); // value per combined normalized size
154
+ runHeuristic([&](int i) { return (double)v[i] / std::max(mNorm[i], lNorm[i]); }); // value per max normalized
155
+ runHeuristic([&](int i) {
156
+ double s = mNorm[i] * mNorm[i] + lNorm[i] * lNorm[i];
157
+ return (double)v[i] / s;
158
+ });
159
+ runHeuristic([&](int i) { return 1.0 / (mNorm[i] + lNorm[i]); }); // prioritize small items
160
+
161
+ // Directional heuristics
162
+ const int K_dir = 32;
163
+ const double PI = acos(-1.0);
164
+ for (int k = 0; k <= K_dir; ++k) {
165
+ double theta = (PI / 2.0) * k / (double)K_dir;
166
+ double alpha = cos(theta);
167
+ double beta = sin(theta);
168
+ runHeuristic([&](int i) {
169
+ double cons = alpha * mNorm[i] + beta * lNorm[i];
170
+ return (double)v[i] / cons;
171
+ });
172
+ }
173
+
174
+ // Local search improvement
175
+ long long usedM = 0, usedL = 0;
176
+ for (int i = 0; i < n; ++i) {
177
+ usedM += bestX[i] * m[i];
178
+ usedL += bestX[i] * l[i];
179
+ }
180
+
181
+ auto tryExchangeType = [&](int addIdx, vector<long long> &x, long long &curUsedM,
182
+ long long &curUsedL, long long &curVal) -> bool {
183
+ if (x[addIdx] >= q[addIdx]) return false;
184
+
185
+ long long M_rem = M_CAP - curUsedM;
186
+ long long L_rem = L_CAP - curUsedL;
187
+
188
+ if (m[addIdx] <= M_rem && l[addIdx] <= L_rem) {
189
+ x[addIdx] += 1;
190
+ curUsedM += m[addIdx];
191
+ curUsedL += l[addIdx];
192
+ curVal += v[addIdx];
193
+ return true;
194
+ }
195
+
196
+ long long mass_needed = std::max(0LL, m[addIdx] - M_rem);
197
+ long long vol_needed = std::max(0LL, l[addIdx] - L_rem);
198
+ long long w_m = mass_needed;
199
+ long long w_l = vol_needed;
200
+
201
+ if (w_m == 0 && w_l == 0) {
202
+ x[addIdx] += 1;
203
+ curUsedM += m[addIdx];
204
+ curUsedL += l[addIdx];
205
+ curVal += v[addIdx];
206
+ return true;
207
+ }
208
+
209
+ vector<int> cand;
210
+ cand.reserve(n);
211
+ for (int i = 0; i < n; ++i) {
212
+ if (i == addIdx) continue;
213
+ if (x[i] > 0) cand.push_back(i);
214
+ }
215
+ if (cand.empty()) return false;
216
+
217
+ struct Node {
218
+ double score;
219
+ int idx;
220
+ };
221
+ vector<Node> nodes;
222
+ nodes.reserve(cand.size());
223
+ for (int i : cand) {
224
+ long long denom_ll = w_m * m[i] + w_l * l[i];
225
+ double denom = (double)denom_ll;
226
+ double score;
227
+ if (denom <= 0.0) score = 1e300;
228
+ else score = (double)v[i] / denom;
229
+ nodes.push_back({score, i});
230
+ }
231
+ sort(nodes.begin(), nodes.end(), [](const Node &a, const Node &b) {
232
+ return a.score < b.score; // remove lowest score first
233
+ });
234
+
235
+ vector<long long> removeCnt(n, 0);
236
+ long long freedM = 0, freedL = 0, valueLoss = 0;
237
+ for (const auto &nd : nodes) {
238
+ if (freedM >= mass_needed && freedL >= vol_needed) break;
239
+ int i = nd.idx;
240
+ long long available = x[i] - removeCnt[i];
241
+ if (available <= 0) continue;
242
+
243
+ long long remMassNeed = std::max(0LL, mass_needed - freedM);
244
+ long long remVolNeed = std::max(0LL, vol_needed - freedL);
245
+ if (remMassNeed <= 0 && remVolNeed <= 0) break;
246
+
247
+ long long unitsByM = remMassNeed > 0 ? ((remMassNeed + m[i] - 1) / m[i]) : 0;
248
+ long long unitsByL = remVolNeed > 0 ? ((remVolNeed + l[i] - 1) / l[i]) : 0;
249
+ long long unitsNeed = std::max(unitsByM, unitsByL);
250
+ if (unitsNeed <= 0) unitsNeed = 1;
251
+ if (unitsNeed > available) unitsNeed = available;
252
+
253
+ freedM += unitsNeed * m[i];
254
+ freedL += unitsNeed * l[i];
255
+ valueLoss += unitsNeed * v[i];
256
+ removeCnt[i] += unitsNeed;
257
+ }
258
+
259
+ if (freedM < mass_needed || freedL < vol_needed) return false;
260
+
261
+ long long netGain = v[addIdx] - valueLoss;
262
+ if (netGain <= 0) return false;
263
+
264
+ // Commit changes
265
+ x[addIdx] += 1;
266
+ curUsedM += m[addIdx];
267
+ curUsedL += l[addIdx];
268
+ curVal += v[addIdx];
269
+ for (int i = 0; i < n; ++i) {
270
+ long long c = removeCnt[i];
271
+ if (c > 0) {
272
+ x[i] -= c;
273
+ curUsedM -= c * m[i];
274
+ curUsedL -= c * l[i];
275
+ curVal -= c * v[i];
276
+ }
277
+ }
278
+ return true;
279
+ };
280
+
281
+ const int MAX_IMPROVE_STEPS = 2000;
282
+ int improveCount = 0;
283
+ bool improved = true;
284
+ while (improved && improveCount < MAX_IMPROVE_STEPS) {
285
+ improved = false;
286
+ for (int j = 0; j < n && improveCount < MAX_IMPROVE_STEPS; ++j) {
287
+ if (tryExchangeType(j, bestX, usedM, usedL, bestVal)) {
288
+ improved = true;
289
+ ++improveCount;
290
+ }
291
+ }
292
+ }
293
+
294
+ // Output JSON
295
+ cout << "{\n";
296
+ for (int i = 0; i < n; ++i) {
297
+ cout << " \"" << names[i] << "\": " << bestX[i];
298
+ if (i + 1 < n) cout << ",\n";
299
+ else cout << "\n";
300
+ }
301
+ cout << "}\n";
302
+
303
+ return 0;
304
+ }
docker_space/frontier_cs_1/examples/gpt5.1_2.cpp ADDED
@@ -0,0 +1,302 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <bits/stdc++.h>
2
+ using namespace std;
3
+
4
+ struct Item {
5
+ string name;
6
+ long long q, v, m, l;
7
+ };
8
+
9
+ const long long MAX_MASS = 20000000LL;
10
+ const long long MAX_VOL = 25000000LL;
11
+ const double EPS = 1e-12;
12
+
13
+ vector<Item> items;
14
+ int n;
15
+
16
+ void skipWhitespace(const string &s, size_t &pos) {
17
+ while (pos < s.size() && isspace((unsigned char)s[pos])) pos++;
18
+ }
19
+
20
+ string parseString(const string &s, size_t &pos) {
21
+ skipWhitespace(s, pos);
22
+ if (pos >= s.size() || s[pos] != '"') return "";
23
+ pos++;
24
+ size_t start = pos;
25
+ while (pos < s.size() && s[pos] != '"') pos++;
26
+ string res = s.substr(start, pos - start);
27
+ if (pos < s.size() && s[pos] == '"') pos++;
28
+ return res;
29
+ }
30
+
31
+ long long parseInt(const string &s, size_t &pos) {
32
+ skipWhitespace(s, pos);
33
+ bool neg = false;
34
+ if (pos < s.size() && s[pos] == '-') {
35
+ neg = true;
36
+ pos++;
37
+ }
38
+ long long val = 0;
39
+ while (pos < s.size() && isdigit((unsigned char)s[pos])) {
40
+ val = val * 10 + (s[pos] - '0');
41
+ pos++;
42
+ }
43
+ return neg ? -val : val;
44
+ }
45
+
46
+ enum Mode { MASS, VOL, SUMD, MASS_HEAVY, VOL_HEAVY, MAXR, VALUE_ONLY };
47
+
48
+ double computeScore(Mode mode, int idx) {
49
+ const Item &it = items[idx];
50
+ double mRel = (double)it.m / (double)MAX_MASS;
51
+ double lRel = (double)it.l / (double)MAX_VOL;
52
+ switch (mode) {
53
+ case MASS:
54
+ return (double)it.v / (double)it.m;
55
+ case VOL:
56
+ return (double)it.v / (double)it.l;
57
+ case SUMD: {
58
+ double denom = mRel + lRel + EPS;
59
+ return (double)it.v / denom;
60
+ }
61
+ case MASS_HEAVY: {
62
+ double denom = 0.7 * mRel + 0.3 * lRel + EPS;
63
+ return (double)it.v / denom;
64
+ }
65
+ case VOL_HEAVY: {
66
+ double denom = 0.3 * mRel + 0.7 * lRel + EPS;
67
+ return (double)it.v / denom;
68
+ }
69
+ case MAXR: {
70
+ double denom = max(mRel, lRel) + EPS;
71
+ return (double)it.v / denom;
72
+ }
73
+ case VALUE_ONLY:
74
+ default:
75
+ return (double)it.v;
76
+ }
77
+ }
78
+
79
+ vector<int> getOrder(Mode mode) {
80
+ vector<int> idx(n);
81
+ iota(idx.begin(), idx.end(), 0);
82
+ sort(idx.begin(), idx.end(), [&](int a, int b) {
83
+ double sa = computeScore(mode, a);
84
+ double sb = computeScore(mode, b);
85
+ if (sa != sb) return sa > sb;
86
+ const Item &ia = items[a];
87
+ const Item &ib = items[b];
88
+ double wa = (double)ia.m / MAX_MASS + (double)ia.l / MAX_VOL;
89
+ double wb = (double)ib.m / MAX_MASS + (double)ib.l / MAX_VOL;
90
+ if (wa != wb) return wa < wb;
91
+ return a < b;
92
+ });
93
+ return idx;
94
+ }
95
+
96
+ vector<long long> greedyPack(Mode mode) {
97
+ vector<int> order = getOrder(mode);
98
+ vector<long long> x(n, 0);
99
+ long long massUsed = 0, volUsed = 0;
100
+ for (int id : order) {
101
+ const Item &it = items[id];
102
+ if (it.m > MAX_MASS || it.l > MAX_VOL) continue;
103
+ long long remM = MAX_MASS - massUsed;
104
+ long long remL = MAX_VOL - volUsed;
105
+ if (remM <= 0 || remL <= 0) break;
106
+ long long maxByM = remM / it.m;
107
+ long long maxByL = remL / it.l;
108
+ long long take = min(it.q, min(maxByM, maxByL));
109
+ if (take > 0) {
110
+ x[id] += take;
111
+ massUsed += take * it.m;
112
+ volUsed += take * it.l;
113
+ }
114
+ }
115
+ return x;
116
+ }
117
+
118
+ long long evaluateSolution(const vector<long long> &x) {
119
+ long long massUsed = 0, volUsed = 0, val = 0;
120
+ for (int i = 0; i < n; i++) {
121
+ if (x[i] < 0 || x[i] > items[i].q) return -1;
122
+ massUsed += x[i] * items[i].m;
123
+ if (massUsed > MAX_MASS) return -1;
124
+ volUsed += x[i] * items[i].l;
125
+ if (volUsed > MAX_VOL) return -1;
126
+ val += x[i] * items[i].v;
127
+ }
128
+ return val;
129
+ }
130
+
131
+ void fillRemByMode(vector<long long> &x, Mode mode) {
132
+ vector<int> order = getOrder(mode);
133
+ long long massUsed = 0, volUsed = 0;
134
+ for (int i = 0; i < n; i++) {
135
+ massUsed += x[i] * items[i].m;
136
+ volUsed += x[i] * items[i].l;
137
+ }
138
+ long long remM = MAX_MASS - massUsed;
139
+ long long remL = MAX_VOL - volUsed;
140
+ if (remM <= 0 || remL <= 0) return;
141
+ for (int id : order) {
142
+ const Item &it = items[id];
143
+ if (x[id] >= it.q) continue;
144
+ if (it.m > remM || it.l > remL) continue;
145
+ long long maxByM = remM / it.m;
146
+ long long maxByL = remL / it.l;
147
+ long long canAdd = min(it.q - x[id], min(maxByM, maxByL));
148
+ if (canAdd > 0) {
149
+ x[id] += canAdd;
150
+ remM -= canAdd * it.m;
151
+ remL -= canAdd * it.l;
152
+ if (remM <= 0 || remL <= 0) break;
153
+ }
154
+ }
155
+ }
156
+
157
+ vector<long long> localSearch(const vector<long long> &start) {
158
+ vector<long long> cur = start;
159
+ fillRemByMode(cur, SUMD);
160
+ const int MAX_ITER = 40;
161
+ const int MAX_REMOVE = 3;
162
+ for (int iter = 0; iter < MAX_ITER; ++iter) {
163
+ long long massUsed = 0, volUsed = 0, curVal = 0;
164
+ for (int i = 0; i < n; i++) {
165
+ massUsed += cur[i] * items[i].m;
166
+ volUsed += cur[i] * items[i].l;
167
+ curVal += cur[i] * items[i].v;
168
+ }
169
+ long long remM = MAX_MASS - massUsed;
170
+ long long remL = MAX_VOL - volUsed;
171
+ long long bestDelta = 0;
172
+ int bestI = -1, bestJ = -1;
173
+ long long bestRemCnt = 0, bestAddCnt = 0;
174
+
175
+ for (int i = 0; i < n; i++) {
176
+ if (cur[i] == 0) continue;
177
+ const Item &itI = items[i];
178
+ long long maxRem = min(cur[i], (long long)MAX_REMOVE);
179
+ for (long long remCnt = 1; remCnt <= maxRem; ++remCnt) {
180
+ long long freedM = remCnt * itI.m;
181
+ long long freedL = remCnt * itI.l;
182
+ long long M2 = remM + freedM;
183
+ long long L2 = remL + freedL;
184
+ if (M2 <= 0 || L2 <= 0) continue;
185
+ for (int j = 0; j < n; j++) {
186
+ if (j == i) continue;
187
+ const Item &itJ = items[j];
188
+ if (cur[j] >= itJ.q) continue;
189
+ if (itJ.m > M2 || itJ.l > L2) continue;
190
+ long long maxByM = M2 / itJ.m;
191
+ long long maxByL = L2 / itJ.l;
192
+ long long addCnt = min(itJ.q - cur[j], min(maxByM, maxByL));
193
+ if (addCnt <= 0) continue;
194
+ long long delta = addCnt * itJ.v - remCnt * itI.v;
195
+ if (delta > bestDelta) {
196
+ bestDelta = delta;
197
+ bestI = i; bestJ = j;
198
+ bestRemCnt = remCnt; bestAddCnt = addCnt;
199
+ }
200
+ }
201
+ }
202
+ }
203
+
204
+ if (bestDelta <= 0) break;
205
+ cur[bestI] -= bestRemCnt;
206
+ cur[bestJ] += bestAddCnt;
207
+ fillRemByMode(cur, SUMD);
208
+ }
209
+ return cur;
210
+ }
211
+
212
+ int main() {
213
+ ios::sync_with_stdio(false);
214
+ cin.tie(nullptr);
215
+
216
+ string input((istreambuf_iterator<char>(cin)), istreambuf_iterator<char>());
217
+ size_t pos = 0;
218
+ skipWhitespace(input, pos);
219
+ if (pos < input.size() && input[pos] == '{') pos++;
220
+ skipWhitespace(input, pos);
221
+ items.clear();
222
+
223
+ while (pos < input.size()) {
224
+ skipWhitespace(input, pos);
225
+ if (pos < input.size() && input[pos] == '}') {
226
+ pos++;
227
+ break;
228
+ }
229
+ string key = parseString(input, pos);
230
+ skipWhitespace(input, pos);
231
+ if (pos < input.size() && input[pos] == ':') pos++;
232
+ skipWhitespace(input, pos);
233
+ if (pos < input.size() && input[pos] == '[') pos++;
234
+
235
+ vector<long long> nums;
236
+ for (int k = 0; k < 4; k++) {
237
+ long long v = parseInt(input, pos);
238
+ nums.push_back(v);
239
+ skipWhitespace(input, pos);
240
+ if (k < 3 && pos < input.size() && input[pos] == ',') {
241
+ pos++;
242
+ skipWhitespace(input, pos);
243
+ }
244
+ }
245
+ skipWhitespace(input, pos);
246
+ if (pos < input.size() && input[pos] == ']') pos++;
247
+
248
+ if (nums.size() == 4) {
249
+ Item it;
250
+ it.name = key;
251
+ it.q = nums[0];
252
+ it.v = nums[1];
253
+ it.m = nums[2];
254
+ it.l = nums[3];
255
+ items.push_back(it);
256
+ }
257
+
258
+ skipWhitespace(input, pos);
259
+ if (pos < input.size() && input[pos] == ',') {
260
+ pos++;
261
+ continue;
262
+ } else if (pos < input.size() && input[pos] == '}') {
263
+ pos++;
264
+ break;
265
+ }
266
+ }
267
+
268
+ n = (int)items.size();
269
+ if (n == 0) {
270
+ cout << "{\n}\n";
271
+ return 0;
272
+ }
273
+
274
+ vector<Mode> modes = { MASS, VOL, SUMD, MASS_HEAVY, VOL_HEAVY, MAXR, VALUE_ONLY };
275
+
276
+ vector<long long> bestSol(n, 0);
277
+ long long bestVal = evaluateSolution(bestSol); // initial 0
278
+
279
+ for (Mode m : modes) {
280
+ vector<long long> sol = greedyPack(m);
281
+ sol = localSearch(sol);
282
+ long long val = evaluateSolution(sol);
283
+ if (val > bestVal) {
284
+ bestVal = val;
285
+ bestSol = sol;
286
+ }
287
+ }
288
+
289
+ if (evaluateSolution(bestSol) < 0) {
290
+ bestSol.assign(n, 0);
291
+ }
292
+
293
+ cout << "{\n";
294
+ for (int i = 0; i < n; i++) {
295
+ cout << " \"" << items[i].name << "\": " << bestSol[i];
296
+ if (i + 1 < n) cout << ",\n";
297
+ else cout << "\n";
298
+ }
299
+ cout << "}\n";
300
+
301
+ return 0;
302
+ }
docker_space/frontier_cs_1/examples/gpt5.1_3.cpp ADDED
@@ -0,0 +1,353 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <bits/stdc++.h>
2
+ using namespace std;
3
+
4
+ // Capacities in mg and µL
5
+ const long long MASS_CAP = 20LL * 1000000LL;
6
+ const long long VOL_CAP = 25LL * 1000000LL;
7
+
8
+ // Global item data
9
+ vector<string> names;
10
+ vector<int> qty;
11
+ vector<long long> val, massv, volv;
12
+
13
+ // JSON parsing globals
14
+ string json_input;
15
+ size_t pos_json = 0;
16
+
17
+ void skip_ws() {
18
+ while (pos_json < json_input.size() &&
19
+ isspace((unsigned char)json_input[pos_json])) {
20
+ ++pos_json;
21
+ }
22
+ }
23
+
24
+ string parse_string() {
25
+ skip_ws();
26
+ if (pos_json >= json_input.size() || json_input[pos_json] != '"') return "";
27
+ ++pos_json; // skip opening quote
28
+ string res;
29
+ while (pos_json < json_input.size() && json_input[pos_json] != '"') {
30
+ res.push_back(json_input[pos_json++]);
31
+ }
32
+ if (pos_json < json_input.size() && json_input[pos_json] == '"') ++pos_json;
33
+ return res;
34
+ }
35
+
36
+ long long parse_ll() {
37
+ skip_ws();
38
+ int sign = 1;
39
+ if (pos_json < json_input.size() && json_input[pos_json] == '-') {
40
+ sign = -1;
41
+ ++pos_json;
42
+ }
43
+ long long v = 0;
44
+ while (pos_json < json_input.size() &&
45
+ isdigit((unsigned char)json_input[pos_json])) {
46
+ v = v * 10 + (json_input[pos_json] - '0');
47
+ ++pos_json;
48
+ }
49
+ return sign * v;
50
+ }
51
+
52
+ void build_greedy(int heurType, vector<int> &x) {
53
+ int n = (int)names.size();
54
+ x.assign(n, 0);
55
+ vector<double> ratio(n);
56
+
57
+ for (int i = 0; i < n; ++i) {
58
+ double cost = 0.0;
59
+ double m = (double)massv[i];
60
+ double l = (double)volv[i];
61
+ double nm = m / (double)MASS_CAP;
62
+ double nl = l / (double)VOL_CAP;
63
+ switch (heurType) {
64
+ case 0: // value per mass
65
+ cost = m;
66
+ break;
67
+ case 1: // value per volume
68
+ cost = l;
69
+ break;
70
+ case 2: // equal normalized
71
+ cost = nm + nl;
72
+ break;
73
+ case 3: // bias mass
74
+ cost = 0.7 * nm + 0.3 * nl;
75
+ break;
76
+ case 4: // bias volume
77
+ cost = 0.3 * nm + 0.7 * nl;
78
+ break;
79
+ case 5: // max normalized
80
+ cost = max(nm, nl);
81
+ break;
82
+ case 6: { // L2 squared
83
+ cost = nm * nm + nl * nl;
84
+ break;
85
+ }
86
+ default:
87
+ cost = nm + nl;
88
+ break;
89
+ }
90
+ if (cost <= 0.0) cost = 1e-9;
91
+ ratio[i] = (double)val[i] / cost;
92
+ }
93
+
94
+ vector<int> order(n);
95
+ iota(order.begin(), order.end(), 0);
96
+ sort(order.begin(), order.end(), [&](int a, int b) {
97
+ if (ratio[a] == ratio[b]) {
98
+ long long ca = massv[a] + volv[a];
99
+ long long cb = massv[b] + volv[b];
100
+ if (ca != cb) return ca < cb;
101
+ return a < b;
102
+ }
103
+ return ratio[a] > ratio[b];
104
+ });
105
+
106
+ long long Mrem = MASS_CAP;
107
+ long long Lrem = VOL_CAP;
108
+
109
+ for (int idx : order) {
110
+ if (Mrem <= 0 || Lrem <= 0) break;
111
+ if (massv[idx] <= 0 || volv[idx] <= 0) continue;
112
+ long long maxK1 = qty[idx];
113
+ long long maxK2 = Mrem / massv[idx];
114
+ long long maxK3 = Lrem / volv[idx];
115
+ long long k = min(maxK1, min(maxK2, maxK3));
116
+ if (k <= 0) continue;
117
+ x[idx] += (int)k;
118
+ Mrem -= k * massv[idx];
119
+ Lrem -= k * volv[idx];
120
+ }
121
+ }
122
+
123
+ long long improve(vector<int> &x) {
124
+ int n = (int)names.size();
125
+ long long Mcur = 0, Lcur = 0, Vcur = 0;
126
+ for (int i = 0; i < n; ++i) {
127
+ Mcur += (long long)x[i] * massv[i];
128
+ Lcur += (long long)x[i] * volv[i];
129
+ Vcur += (long long)x[i] * val[i];
130
+ }
131
+
132
+ auto fill_capacity = [&]() {
133
+ while (true) {
134
+ long long Mfree = MASS_CAP - Mcur;
135
+ long long Lfree = VOL_CAP - Lcur;
136
+ if (Mfree <= 0 || Lfree <= 0) break;
137
+ long long bestGain = 0;
138
+ int bestJ = -1;
139
+ long long bestK = 0;
140
+ for (int j = 0; j < n; ++j) {
141
+ if (x[j] >= qty[j]) continue;
142
+ if (massv[j] > Mfree || volv[j] > Lfree) continue;
143
+ long long maxK1 = (long long)qty[j] - x[j];
144
+ long long maxK2 = Mfree / massv[j];
145
+ long long maxK3 = Lfree / volv[j];
146
+ long long k = min(maxK1, min(maxK2, maxK3));
147
+ if (k <= 0) continue;
148
+ long long gain = k * val[j];
149
+ if (gain > bestGain) {
150
+ bestGain = gain;
151
+ bestJ = j;
152
+ bestK = k;
153
+ }
154
+ }
155
+ if (bestJ == -1) break;
156
+ x[bestJ] += (int)bestK;
157
+ Mcur += bestK * massv[bestJ];
158
+ Lcur += bestK * volv[bestJ];
159
+ Vcur += bestGain;
160
+ }
161
+ };
162
+
163
+ fill_capacity();
164
+
165
+ const int MAX_ITERS = 60;
166
+ for (int iter = 0; iter < MAX_ITERS; ++iter) {
167
+ long long bestDV = 0;
168
+ int moveType = 0; // 0 none, 1 one-drop, 2 two-drop
169
+ int bi1 = -1, bi2 = -1, bj = -1;
170
+ long long bk = 0;
171
+
172
+ // One-drop moves: remove 1 of i, add k of j
173
+ for (int i = 0; i < n; ++i) {
174
+ if (x[i] <= 0) continue;
175
+ for (int j = 0; j < n; ++j) {
176
+ if (j == i) continue;
177
+ if (x[j] >= qty[j]) continue;
178
+ long long Mfree = MASS_CAP - (Mcur - massv[i]);
179
+ long long Lfree = VOL_CAP - (Lcur - volv[i]);
180
+ if (Mfree <= 0 || Lfree <= 0) continue;
181
+ if (massv[j] > Mfree || volv[j] > Lfree) continue;
182
+ long long maxK1 = (long long)qty[j] - x[j];
183
+ long long maxK2 = Mfree / massv[j];
184
+ long long maxK3 = Lfree / volv[j];
185
+ long long k = min(maxK1, min(maxK2, maxK3));
186
+ if (k <= 0) continue;
187
+ long long DV = -val[i] + k * val[j];
188
+ if (DV > bestDV) {
189
+ bestDV = DV;
190
+ moveType = 1;
191
+ bi1 = i;
192
+ bj = j;
193
+ bk = k;
194
+ }
195
+ }
196
+ }
197
+
198
+ // Two-drop moves: remove 2 items (a,b), add k of j
199
+ for (int a = 0; a < n; ++a) {
200
+ if (x[a] <= 0) continue;
201
+ for (int b = a; b < n; ++b) {
202
+ if (b == a) {
203
+ if (x[a] < 2) continue;
204
+ } else {
205
+ if (x[b] <= 0) continue;
206
+ }
207
+ long long removeMass = massv[a] + (b == a ? massv[a] : massv[b]);
208
+ long long removeVol = volv[a] + (b == a ? volv[a] : volv[b]);
209
+ long long McurP = Mcur - removeMass;
210
+ long long LcurP = Lcur - removeVol;
211
+ if (McurP < 0 || LcurP < 0) continue;
212
+ long long Mfree = MASS_CAP - McurP;
213
+ long long Lfree = VOL_CAP - LcurP;
214
+ if (Mfree <= 0 || Lfree <= 0) continue;
215
+
216
+ for (int j = 0; j < n; ++j) {
217
+ if (j == a || j == b) continue;
218
+ if (x[j] >= qty[j]) continue;
219
+ if (massv[j] > Mfree || volv[j] > Lfree) continue;
220
+ long long maxK1 = (long long)qty[j] - x[j];
221
+ long long maxK2 = Mfree / massv[j];
222
+ long long maxK3 = Lfree / volv[j];
223
+ long long k = min(maxK1, min(maxK2, maxK3));
224
+ if (k <= 0) continue;
225
+ long long DV = -val[a] - (b == a ? val[a] : val[b]) + k * val[j];
226
+ if (DV > bestDV) {
227
+ bestDV = DV;
228
+ moveType = 2;
229
+ bi1 = a;
230
+ bi2 = b;
231
+ bj = j;
232
+ bk = k;
233
+ }
234
+ }
235
+ }
236
+ }
237
+
238
+ if (bestDV <= 0 || moveType == 0) break;
239
+
240
+ if (moveType == 1) {
241
+ x[bi1]--;
242
+ x[bj] += (int)bk;
243
+ Mcur = Mcur - massv[bi1] + bk * massv[bj];
244
+ Lcur = Lcur - volv[bi1] + bk * volv[bj];
245
+ } else { // moveType == 2
246
+ x[bi1]--;
247
+ x[bi2]--;
248
+ x[bj] += (int)bk;
249
+ long long removeMass = massv[bi1] + (bi2 == bi1 ? massv[bi1] : massv[bi2]);
250
+ long long removeVol = volv[bi1] + (bi2 == bi1 ? volv[bi1] : volv[bi2]);
251
+ Mcur = Mcur - removeMass + bk * massv[bj];
252
+ Lcur = Lcur - removeVol + bk * volv[bj];
253
+ }
254
+ Vcur += bestDV;
255
+
256
+ fill_capacity();
257
+ }
258
+
259
+ return Vcur;
260
+ }
261
+
262
+ int main() {
263
+ ios::sync_with_stdio(false);
264
+ cin.tie(nullptr);
265
+
266
+ json_input.assign(istreambuf_iterator<char>(cin), istreambuf_iterator<char>());
267
+ pos_json = 0;
268
+
269
+ skip_ws();
270
+ if (pos_json < json_input.size() && json_input[pos_json] == '{') ++pos_json;
271
+
272
+ names.clear();
273
+ qty.clear();
274
+ val.clear();
275
+ massv.clear();
276
+ volv.clear();
277
+
278
+ while (true) {
279
+ skip_ws();
280
+ if (pos_json >= json_input.size()) break;
281
+ if (json_input[pos_json] == '}') {
282
+ ++pos_json;
283
+ break;
284
+ }
285
+
286
+ string key = parse_string();
287
+ skip_ws();
288
+ if (pos_json < json_input.size() && json_input[pos_json] == ':') ++pos_json;
289
+ skip_ws();
290
+ if (pos_json < json_input.size() && json_input[pos_json] == '[') ++pos_json;
291
+
292
+ long long qv = parse_ll();
293
+ skip_ws();
294
+ if (pos_json < json_input.size() && json_input[pos_json] == ',') ++pos_json;
295
+ long long vv = parse_ll();
296
+ skip_ws();
297
+ if (pos_json < json_input.size() && json_input[pos_json] == ',') ++pos_json;
298
+ long long mv = parse_ll();
299
+ skip_ws();
300
+ if (pos_json < json_input.size() && json_input[pos_json] == ',') ++pos_json;
301
+ long long lv = parse_ll();
302
+ skip_ws();
303
+ if (pos_json < json_input.size() && json_input[pos_json] == ']') ++pos_json;
304
+
305
+ names.push_back(key);
306
+ qty.push_back((int)qv);
307
+ val.push_back(vv);
308
+ massv.push_back(mv);
309
+ volv.push_back(lv);
310
+
311
+ skip_ws();
312
+ if (pos_json < json_input.size() && json_input[pos_json] == ',') {
313
+ ++pos_json;
314
+ continue;
315
+ }
316
+ }
317
+
318
+ int n = (int)names.size();
319
+ vector<int> bestX(n, 0);
320
+ long long bestValue = -1;
321
+
322
+ // Heuristic greedy starts
323
+ for (int ht = 0; ht < 7; ++ht) {
324
+ vector<int> x(n, 0);
325
+ build_greedy(ht, x);
326
+ long long vsol = improve(x);
327
+ if (vsol > bestValue) {
328
+ bestValue = vsol;
329
+ bestX = x;
330
+ }
331
+ }
332
+
333
+ // Start from empty as additional candidate
334
+ {
335
+ vector<int> x(n, 0);
336
+ long long vsol = improve(x);
337
+ if (vsol > bestValue) {
338
+ bestValue = vsol;
339
+ bestX = x;
340
+ }
341
+ }
342
+
343
+ // Output JSON
344
+ cout << "{\n";
345
+ for (int i = 0; i < n; ++i) {
346
+ cout << " \"" << names[i] << "\": " << bestX[i];
347
+ if (i + 1 < n) cout << ",\n";
348
+ else cout << "\n";
349
+ }
350
+ cout << "}\n";
351
+
352
+ return 0;
353
+ }
docker_space/frontier_cs_1/examples/gpt5.1_4.cpp ADDED
@@ -0,0 +1,308 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <bits/stdc++.h>
2
+ using namespace std;
3
+
4
+ struct Item {
5
+ string name;
6
+ long long q, v, m, l;
7
+ long long max_take;
8
+ };
9
+
10
+ const long long CAP_M = 20000000LL;
11
+ const long long CAP_L = 25000000LL;
12
+
13
+ vector<Item> items;
14
+ int n_items = 0;
15
+
16
+ void parse_input() {
17
+ ios::sync_with_stdio(false);
18
+ cin.tie(nullptr);
19
+ string s((istreambuf_iterator<char>(cin)), istreambuf_iterator<char>());
20
+ int len = (int)s.size();
21
+ int pos = 0;
22
+
23
+ auto skip_ws = [&]() {
24
+ while (pos < len && isspace((unsigned char)s[pos])) pos++;
25
+ };
26
+
27
+ skip_ws();
28
+ if (pos < len && s[pos] == '{') pos++;
29
+
30
+ while (pos < len) {
31
+ skip_ws();
32
+ if (pos >= len) break;
33
+ if (s[pos] == '}') { pos++; break; }
34
+ if (s[pos] == ',') { pos++; continue; }
35
+
36
+ skip_ws();
37
+ if (pos >= len || s[pos] != '"') break;
38
+ pos++; // skip opening quote
39
+ string name;
40
+ while (pos < len && s[pos] != '"') {
41
+ name.push_back(s[pos]);
42
+ pos++;
43
+ }
44
+ if (pos < len && s[pos] == '"') pos++; // closing quote
45
+
46
+ skip_ws();
47
+ if (pos < len && s[pos] == ':') pos++;
48
+ skip_ws();
49
+ if (pos < len && s[pos] == '[') pos++;
50
+
51
+ vector<long long> arr;
52
+ arr.reserve(4);
53
+ for (int k = 0; k < 4; k++) {
54
+ skip_ws();
55
+ long long sign = 1;
56
+ if (pos < len && s[pos] == '-') {
57
+ sign = -1;
58
+ pos++;
59
+ }
60
+ long long val = 0;
61
+ while (pos < len && isdigit((unsigned char)s[pos])) {
62
+ val = val * 10 + (s[pos] - '0');
63
+ pos++;
64
+ }
65
+ arr.push_back(sign * val);
66
+ skip_ws();
67
+ if (k < 3 && pos < len && s[pos] == ',') pos++;
68
+ }
69
+ skip_ws();
70
+ if (pos < len && s[pos] == ']') pos++;
71
+
72
+ Item it;
73
+ it.name = name;
74
+ it.q = arr[0];
75
+ it.v = arr[1];
76
+ it.m = arr[2];
77
+ it.l = arr[3];
78
+ it.max_take = 0; // to be set later
79
+ items.push_back(it);
80
+
81
+ skip_ws();
82
+ if (pos < len && s[pos] == ',') { pos++; continue; }
83
+ }
84
+
85
+ n_items = (int)items.size();
86
+ }
87
+
88
+ long long evalSolution(const vector<long long>& x) {
89
+ long long val = 0;
90
+ for (int i = 0; i < n_items; i++) {
91
+ val += x[i] * items[i].v;
92
+ }
93
+ return val;
94
+ }
95
+
96
+ long long greedy_fill(const vector<int>& order, vector<long long>& x, long long& massUsed, long long& volUsed) {
97
+ long long rM = CAP_M - massUsed;
98
+ long long rL = CAP_L - volUsed;
99
+ for (int idx : order) {
100
+ int i = idx;
101
+ if (items[i].max_take <= x[i]) continue;
102
+ long long avail = items[i].max_take - x[i];
103
+ if (avail <= 0) continue;
104
+ if (items[i].m > 0) {
105
+ long long byM = rM / items[i].m;
106
+ if (byM < avail) avail = byM;
107
+ }
108
+ if (items[i].l > 0) {
109
+ long long byL = rL / items[i].l;
110
+ if (byL < avail) avail = byL;
111
+ }
112
+ if (avail <= 0) continue;
113
+ x[i] += avail;
114
+ long long addM = avail * items[i].m;
115
+ long long addL = avail * items[i].l;
116
+ massUsed += addM;
117
+ volUsed += addL;
118
+ rM -= addM;
119
+ rL -= addL;
120
+ if (rM <= 0 || rL <= 0) break;
121
+ }
122
+ return evalSolution(x);
123
+ }
124
+
125
+ void local_search(vector<long long>& x, long long& value, long long& massUsed, long long& volUsed,
126
+ const vector<int>& refill_order, clock_t t0) {
127
+ const int MAX_ITERS = 100;
128
+ for (int iter = 0; iter < MAX_ITERS; iter++) {
129
+ double elapsed = double(clock() - t0) / CLOCKS_PER_SEC;
130
+ if (elapsed > 0.90) return;
131
+
132
+ bool improved = false;
133
+ long long bestVal = value;
134
+ vector<long long> bestX;
135
+ long long bestMass = massUsed, bestVol = volUsed;
136
+
137
+ // 1-item removal moves
138
+ for (int i = 0; i < n_items; i++) {
139
+ if (x[i] == 0) continue;
140
+ long long lim = min(10LL, x[i]);
141
+ for (long long rem = 1; rem <= lim; rem++) {
142
+ vector<long long> tmp_x = x;
143
+ tmp_x[i] -= rem;
144
+ long long tmpMass = massUsed - rem * items[i].m;
145
+ long long tmpVol = volUsed - rem * items[i].l;
146
+ long long newVal = greedy_fill(refill_order, tmp_x, tmpMass, tmpVol);
147
+ if (newVal > bestVal) {
148
+ bestVal = newVal;
149
+ bestX.swap(tmp_x);
150
+ bestMass = tmpMass;
151
+ bestVol = tmpVol;
152
+ improved = true;
153
+ }
154
+ }
155
+ }
156
+
157
+ // 2-item removal moves
158
+ for (int i = 0; i < n_items; i++) {
159
+ if (x[i] == 0) continue;
160
+ long long limi = min(5LL, x[i]);
161
+ for (int j = i + 1; j < n_items; j++) {
162
+ if (x[j] == 0) continue;
163
+ long long limj = min(5LL, x[j]);
164
+ for (long long remi = 1; remi <= limi; remi++) {
165
+ for (long long remj = 1; remj <= limj; remj++) {
166
+ vector<long long> tmp_x = x;
167
+ tmp_x[i] -= remi;
168
+ tmp_x[j] -= remj;
169
+ long long tmpMass = massUsed - remi * items[i].m - remj * items[j].m;
170
+ long long tmpVol = volUsed - remi * items[i].l - remj * items[j].l;
171
+ long long newVal = greedy_fill(refill_order, tmp_x, tmpMass, tmpVol);
172
+ if (newVal > bestVal) {
173
+ bestVal = newVal;
174
+ bestX.swap(tmp_x);
175
+ bestMass = tmpMass;
176
+ bestVol = tmpVol;
177
+ improved = true;
178
+ }
179
+ }
180
+ }
181
+ }
182
+ }
183
+
184
+ if (!improved) break;
185
+ x.swap(bestX);
186
+ value = bestVal;
187
+ massUsed = bestMass;
188
+ volUsed = bestVol;
189
+ }
190
+ }
191
+
192
+ vector<int> create_order_from_scores(const vector<long double>& scores, bool descending) {
193
+ vector<int> ord(n_items);
194
+ iota(ord.begin(), ord.end(), 0);
195
+ if (descending) {
196
+ sort(ord.begin(), ord.end(), [&](int a, int b) {
197
+ if (scores[a] == scores[b]) return a < b;
198
+ return scores[a] > scores[b];
199
+ });
200
+ } else {
201
+ sort(ord.begin(), ord.end(), [&](int a, int b) {
202
+ if (scores[a] == scores[b]) return a < b;
203
+ return scores[a] < scores[b];
204
+ });
205
+ }
206
+ return ord;
207
+ }
208
+
209
+ int main() {
210
+ parse_input();
211
+ n_items = (int)items.size();
212
+
213
+ // Compute per-item max_take
214
+ for (int i = 0; i < n_items; i++) {
215
+ long long max_by_q = items[i].q;
216
+ long long max_by_m = (items[i].m == 0) ? max_by_q : (CAP_M / items[i].m);
217
+ long long max_by_l = (items[i].l == 0) ? max_by_q : (CAP_L / items[i].l);
218
+ long long mt = max_by_q;
219
+ if (max_by_m < mt) mt = max_by_m;
220
+ if (max_by_l < mt) mt = max_by_l;
221
+ if (mt < 0) mt = 0;
222
+ items[i].max_take = mt;
223
+ }
224
+
225
+ // Build various heuristic orders
226
+ const long double NEG_INF = -1e300L;
227
+ const long double POS_INF = 1e300L;
228
+
229
+ vector<long double> ratioApprox(n_items), ratioMass(n_items), ratioVol(n_items), ratioMax(n_items);
230
+ vector<long double> massScore(n_items), volScore(n_items);
231
+
232
+ for (int i = 0; i < n_items; i++) {
233
+ if (items[i].max_take == 0) {
234
+ ratioApprox[i] = ratioMass[i] = ratioVol[i] = ratioMax[i] = NEG_INF;
235
+ massScore[i] = volScore[i] = POS_INF;
236
+ } else {
237
+ long double wm = (long double)items[i].m / (long double)CAP_M;
238
+ long double wl = (long double)items[i].l / (long double)CAP_L;
239
+ long double denom = wm + wl;
240
+ if (denom <= 0) denom = 1e-18L;
241
+ ratioApprox[i] = (long double)items[i].v / denom;
242
+ ratioMass[i] = (long double)items[i].v / (long double)items[i].m;
243
+ ratioVol[i] = (long double)items[i].v / (long double)items[i].l;
244
+ long double maxCost = max(wm, wl);
245
+ if (maxCost <= 0) maxCost = 1e-18L;
246
+ ratioMax[i] = (long double)items[i].v / maxCost;
247
+ massScore[i] = (long double)items[i].m;
248
+ volScore[i] = (long double)items[i].l;
249
+ }
250
+ }
251
+
252
+ vector<vector<int>> orders;
253
+ orders.push_back(create_order_from_scores(ratioApprox, true));
254
+ orders.push_back(create_order_from_scores(ratioMass, true));
255
+ orders.push_back(create_order_from_scores(ratioVol, true));
256
+ orders.push_back(create_order_from_scores(ratioMax, true));
257
+ orders.push_back(create_order_from_scores(massScore, false)); // light items first
258
+ orders.push_back(create_order_from_scores(volScore, false)); // small volume first
259
+
260
+ mt19937_64 rng(123456);
261
+ uniform_real_distribution<long double> dist(0.8L, 1.2L);
262
+
263
+ for (int t = 0; t < 5; t++) {
264
+ vector<long double> noisy(n_items);
265
+ for (int i = 0; i < n_items; i++) {
266
+ if (items[i].max_take == 0) noisy[i] = NEG_INF;
267
+ else noisy[i] = ratioApprox[i] * dist(rng);
268
+ }
269
+ orders.push_back(create_order_from_scores(noisy, true));
270
+ }
271
+
272
+ vector<int> refill_order = orders.front(); // use approximate ratio as refill order
273
+
274
+ vector<long long> bestX(n_items, 0);
275
+ long long bestVal = 0;
276
+
277
+ clock_t t0 = clock();
278
+
279
+ for (auto &order : orders) {
280
+ double elapsed = double(clock() - t0) / CLOCKS_PER_SEC;
281
+ if (elapsed > 0.95) break;
282
+
283
+ vector<long long> x(n_items, 0);
284
+ long long massUsed = 0, volUsed = 0;
285
+ long long val = greedy_fill(order, x, massUsed, volUsed);
286
+ if (val > bestVal) {
287
+ bestVal = val;
288
+ bestX = x;
289
+ }
290
+
291
+ local_search(x, val, massUsed, volUsed, refill_order, t0);
292
+ if (val > bestVal) {
293
+ bestVal = val;
294
+ bestX = x;
295
+ }
296
+ }
297
+
298
+ // Output JSON with original keys
299
+ cout << "{\n";
300
+ for (int i = 0; i < n_items; i++) {
301
+ cout << " \"" << items[i].name << "\": " << bestX[i];
302
+ if (i + 1 < n_items) cout << ",\n";
303
+ else cout << "\n";
304
+ }
305
+ cout << "}\n";
306
+
307
+ return 0;
308
+ }
docker_space/frontier_cs_1/examples/gpt5.2.cpp ADDED
@@ -0,0 +1,546 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <bits/stdc++.h>
2
+ using namespace std;
3
+
4
+ struct Item {
5
+ string name;
6
+ int q;
7
+ long long v, m, l;
8
+ };
9
+
10
+ static inline void skip_ws(const string& s, size_t& i) {
11
+ while (i < s.size() && isspace((unsigned char)s[i])) i++;
12
+ }
13
+
14
+ static string parse_string(const string& s, size_t& i) {
15
+ skip_ws(s, i);
16
+ if (i >= s.size() || s[i] != '"') return "";
17
+ i++;
18
+ string out;
19
+ while (i < s.size()) {
20
+ char c = s[i++];
21
+ if (c == '"') break;
22
+ if (c == '\\') { // minimal escape support
23
+ if (i < s.size()) {
24
+ char e = s[i++];
25
+ out.push_back(e);
26
+ }
27
+ } else out.push_back(c);
28
+ }
29
+ return out;
30
+ }
31
+
32
+ static long long parse_int(const string& s, size_t& i) {
33
+ skip_ws(s, i);
34
+ bool neg = false;
35
+ if (i < s.size() && s[i] == '-') { neg = true; i++; }
36
+ long long x = 0;
37
+ while (i < s.size() && isdigit((unsigned char)s[i])) {
38
+ x = x * 10 + (s[i] - '0');
39
+ i++;
40
+ }
41
+ return neg ? -x : x;
42
+ }
43
+
44
+ struct Solution {
45
+ array<int,12> x{};
46
+ long long value = 0;
47
+ long long usedM = 0, usedL = 0;
48
+ };
49
+
50
+ static inline long long compute_value(const vector<Item>& items, const array<int,12>& x) {
51
+ long long val = 0;
52
+ for (int i = 0; i < 12; i++) val += (long long)x[i] * items[i].v;
53
+ return val;
54
+ }
55
+
56
+ static inline pair<long long,long long> compute_used(const vector<Item>& items, const array<int,12>& x) {
57
+ __int128 um = 0, ul = 0;
58
+ for (int i = 0; i < 12; i++) {
59
+ um += (__int128)x[i] * items[i].m;
60
+ ul += (__int128)x[i] * items[i].l;
61
+ }
62
+ return {(long long)um, (long long)ul};
63
+ }
64
+
65
+ static Solution greedy(const vector<Item>& items, long long M, long long L, long double alphaM, long double alphaL) {
66
+ vector<int> idx(12);
67
+ iota(idx.begin(), idx.end(), 0);
68
+ vector<long double> score(12, 0);
69
+ for (int i = 0; i < 12; i++) {
70
+ long double denom = alphaM * (long double)items[i].m + alphaL * (long double)items[i].l;
71
+ if (denom <= 0) score[i] = 0;
72
+ else score[i] = (long double)items[i].v / denom;
73
+ }
74
+ stable_sort(idx.begin(), idx.end(), [&](int a, int b){
75
+ if (score[a] != score[b]) return score[a] > score[b];
76
+ return items[a].v > items[b].v;
77
+ });
78
+
79
+ Solution sol;
80
+ long long remM = M, remL = L;
81
+ for (int id : idx) {
82
+ if (items[id].m > remM || items[id].l > remL) continue;
83
+ long long byM = remM / items[id].m;
84
+ long long byL = remL / items[id].l;
85
+ long long take = min<long long>(items[id].q, min(byM, byL));
86
+ sol.x[id] = (int)take;
87
+ remM -= take * items[id].m;
88
+ remL -= take * items[id].l;
89
+ sol.value += take * items[id].v;
90
+ sol.usedM += take * items[id].m;
91
+ sol.usedL += take * items[id].l;
92
+ }
93
+ return sol;
94
+ }
95
+
96
+ struct WeightRun {
97
+ long long p, q; // coefficient k = p/q
98
+ bool volCoeff; // if true: w = m*L*q + l*M*p; else: w = m*L*p + l*M*q
99
+ };
100
+
101
+ struct BeamState {
102
+ array<int,12> x{};
103
+ long long remM = 0, remL = 0;
104
+ long long val = 0;
105
+ long double ub = 0;
106
+ };
107
+
108
+ static long double fractional_bound(
109
+ const vector<Item>& items,
110
+ const vector<int>& order,
111
+ int pos,
112
+ long long remM, long long remL,
113
+ long long M, long long L,
114
+ long long wM1, long long wL1
115
+ ) {
116
+ __int128 remW128 = (__int128)remM * wM1 + (__int128)remL * wL1;
117
+ long long remW = (remW128 > (__int128)LLONG_MAX ? LLONG_MAX : (long long)remW128);
118
+ long double add = 0.0L;
119
+
120
+ for (int k = pos; k < (int)order.size(); k++) {
121
+ int i = order[k];
122
+ long long wi;
123
+ {
124
+ __int128 w128 = (__int128)items[i].m * wM1 + (__int128)items[i].l * wL1;
125
+ if (w128 <= 0) continue;
126
+ wi = (w128 > (__int128)LLONG_MAX ? LLONG_MAX : (long long)w128);
127
+ }
128
+ if (wi <= 0) continue;
129
+
130
+ long long capByM = (items[i].m == 0 ? (long long)items[i].q : remM / items[i].m);
131
+ long long capByL = (items[i].l == 0 ? (long long)items[i].q : remL / items[i].l);
132
+ long long avail = min<long long>(items[i].q, min(capByM, capByL));
133
+ if (avail <= 0) continue;
134
+ if (remW <= 0) break;
135
+
136
+ long long take = min(avail, remW / wi);
137
+ if (take > 0) {
138
+ add += (long double)take * (long double)items[i].v;
139
+ remW -= take * wi;
140
+ remM -= take * items[i].m;
141
+ remL -= take * items[i].l;
142
+ }
143
+ if (take < avail && remW > 0) {
144
+ // fractional
145
+ add += (long double)remW * ((long double)items[i].v / (long double)wi);
146
+ break;
147
+ }
148
+ }
149
+ return add;
150
+ }
151
+
152
+ static Solution beam_search(
153
+ const vector<Item>& items,
154
+ long long M, long long L,
155
+ const WeightRun& wr,
156
+ int BEAM_W
157
+ ) {
158
+ long long wM1, wL1;
159
+ if (wr.volCoeff) {
160
+ // w = m*(L*q) + l*(M*p)
161
+ wM1 = L * wr.q;
162
+ wL1 = M * wr.p;
163
+ } else {
164
+ // w = m*(L*p) + l*(M*q)
165
+ wM1 = L * wr.p;
166
+ wL1 = M * wr.q;
167
+ }
168
+
169
+ vector<int> order(12);
170
+ iota(order.begin(), order.end(), 0);
171
+ vector<long double> dens(12, 0.0L);
172
+ for (int i = 0; i < 12; i++) {
173
+ __int128 w128 = (__int128)items[i].m * wM1 + (__int128)items[i].l * wL1;
174
+ long double wi = (w128 <= 0 ? 1.0L : (long double)(long long)min<__int128>(w128, (__int128)LLONG_MAX));
175
+ dens[i] = (wi <= 0 ? 0.0L : (long double)items[i].v / wi);
176
+ }
177
+ stable_sort(order.begin(), order.end(), [&](int a, int b){
178
+ if (dens[a] != dens[b]) return dens[a] > dens[b];
179
+ // tie-break: prefer higher absolute value
180
+ if (items[a].v != items[b].v) return items[a].v > items[b].v;
181
+ // then smaller combined consumption
182
+ __int128 wa = (__int128)items[a].m * wM1 + (__int128)items[a].l * wL1;
183
+ __int128 wb = (__int128)items[b].m * wM1 + (__int128)items[b].l * wL1;
184
+ return wa < wb;
185
+ });
186
+
187
+ vector<BeamState> beam, nxt;
188
+ beam.reserve(BEAM_W);
189
+ nxt.reserve(BEAM_W * 8);
190
+
191
+ BeamState init;
192
+ init.remM = M; init.remL = L; init.val = 0;
193
+ init.ub = (long double)init.val + fractional_bound(items, order, 0, init.remM, init.remL, M, L, wM1, wL1);
194
+ beam.push_back(init);
195
+
196
+ auto push_state = [&](vector<BeamState>& vec, const BeamState& st){
197
+ vec.push_back(st);
198
+ };
199
+
200
+ for (int pos = 0; pos < 12; pos++) {
201
+ nxt.clear();
202
+ int it = order[pos];
203
+ for (const auto& st : beam) {
204
+ long long remM = st.remM, remL = st.remL;
205
+ long long maxTake = 0;
206
+ if (items[it].m <= remM && items[it].l <= remL) {
207
+ long long byM = remM / items[it].m;
208
+ long long byL = remL / items[it].l;
209
+ maxTake = min<long long>(items[it].q, min(byM, byL));
210
+ }
211
+
212
+ vector<int> cands;
213
+ cands.reserve(12);
214
+ cands.push_back(0);
215
+ if (maxTake > 0) {
216
+ cands.push_back((int)maxTake);
217
+ cands.push_back(1);
218
+ cands.push_back((int)min<long long>(2, maxTake));
219
+ cands.push_back((int)min<long long>(3, maxTake));
220
+ cands.push_back((int)(maxTake / 2));
221
+ cands.push_back((int)(maxTake / 3));
222
+ cands.push_back((int)(maxTake * 3 / 4));
223
+ cands.push_back((int)(maxTake * 4 / 5));
224
+ cands.push_back((int)(maxTake / 5));
225
+ }
226
+ sort(cands.begin(), cands.end());
227
+ cands.erase(unique(cands.begin(), cands.end()), cands.end());
228
+
229
+ for (int take : cands) {
230
+ if (take < 0) continue;
231
+ if ((long long)take > maxTake) continue;
232
+ BeamState ns = st;
233
+ ns.x[it] = take;
234
+ ns.remM = remM - (long long)take * items[it].m;
235
+ ns.remL = remL - (long long)take * items[it].l;
236
+ ns.val = st.val + (long long)take * items[it].v;
237
+ ns.ub = (long double)ns.val + fractional_bound(items, order, pos+1, ns.remM, ns.remL, M, L, wM1, wL1);
238
+ push_state(nxt, ns);
239
+ }
240
+ }
241
+
242
+ // Keep top BEAM_W by (ub, val)
243
+ if ((int)nxt.size() > BEAM_W) {
244
+ nth_element(nxt.begin(), nxt.begin() + BEAM_W, nxt.end(), [](const BeamState& a, const BeamState& b){
245
+ if (a.ub != b.ub) return a.ub > b.ub;
246
+ return a.val > b.val;
247
+ });
248
+ nxt.resize(BEAM_W);
249
+ }
250
+ sort(nxt.begin(), nxt.end(), [](const BeamState& a, const BeamState& b){
251
+ if (a.ub != b.ub) return a.ub > b.ub;
252
+ return a.val > b.val;
253
+ });
254
+
255
+ beam.swap(nxt);
256
+ }
257
+
258
+ // Choose best by value (all feasible)
259
+ Solution best;
260
+ long long bestV = -1;
261
+ for (const auto& st : beam) {
262
+ if (st.val > bestV) {
263
+ bestV = st.val;
264
+ best.x = st.x;
265
+ }
266
+ }
267
+ best.value = bestV;
268
+ auto used = compute_used(items, best.x);
269
+ best.usedM = used.first;
270
+ best.usedL = used.second;
271
+ return best;
272
+ }
273
+
274
+ static Solution local_improve(
275
+ const vector<Item>& items,
276
+ long long M, long long L,
277
+ Solution sol,
278
+ uint64_t seed,
279
+ int ITER
280
+ ) {
281
+ // fixed density based on normalized combined weight: w = m*L + l*M
282
+ vector<int> order(12);
283
+ iota(order.begin(), order.end(), 0);
284
+ vector<long double> dens(12, 0.0L);
285
+ for (int i = 0; i < 12; i++) {
286
+ __int128 w = (__int128)items[i].m * L + (__int128)items[i].l * M;
287
+ long double wi = (w <= 0 ? 1.0L : (long double)(long long)min<__int128>(w, (__int128)LLONG_MAX));
288
+ dens[i] = (wi <= 0 ? 0.0L : (long double)items[i].v / wi);
289
+ }
290
+ stable_sort(order.begin(), order.end(), [&](int a, int b){
291
+ if (dens[a] != dens[b]) return dens[a] > dens[b];
292
+ return items[a].v > items[b].v;
293
+ });
294
+
295
+ auto eval = [&](const array<int,12>& x, long long& usedM, long long& usedL, long long& val) {
296
+ __int128 um = 0, ul = 0, vv = 0;
297
+ for (int i = 0; i < 12; i++) {
298
+ um += (__int128)x[i] * items[i].m;
299
+ ul += (__int128)x[i] * items[i].l;
300
+ vv += (__int128)x[i] * items[i].v;
301
+ }
302
+ usedM = (long long)um;
303
+ usedL = (long long)ul;
304
+ val = (long long)vv;
305
+ };
306
+
307
+ auto refill_greedy = [&](array<int,12>& x) {
308
+ long long usedM, usedL, val;
309
+ eval(x, usedM, usedL, val);
310
+ long long remM = M - usedM;
311
+ long long remL = L - usedL;
312
+ if (remM < 0 || remL < 0) return;
313
+ for (int id : order) {
314
+ int have = x[id];
315
+ int canMore = items[id].q - have;
316
+ if (canMore <= 0) continue;
317
+ if (items[id].m > remM || items[id].l > remL) continue;
318
+ long long add = min<long long>(canMore, min(remM / items[id].m, remL / items[id].l));
319
+ if (add <= 0) continue;
320
+ x[id] += (int)add;
321
+ remM -= add * items[id].m;
322
+ remL -= add * items[id].l;
323
+ }
324
+ };
325
+
326
+ mt19937_64 rng(seed);
327
+
328
+ Solution best = sol;
329
+ if (best.usedM > M || best.usedL > L) {
330
+ // repair (shouldn't happen)
331
+ best.x.fill(0);
332
+ best = greedy(items, M, L, 1.0L/(long double)M, 1.0L/(long double)L);
333
+ }
334
+
335
+ vector<int> nonzero;
336
+ nonzero.reserve(12);
337
+
338
+ for (int it = 0; it < ITER; it++) {
339
+ array<int,12> x = best.x;
340
+
341
+ nonzero.clear();
342
+ for (int i = 0; i < 12; i++) if (x[i] > 0) nonzero.push_back(i);
343
+ if (nonzero.empty()) break;
344
+
345
+ int i = nonzero[(size_t)(rng() % nonzero.size())];
346
+
347
+ int maxRemove = min(x[i], 30);
348
+ if (maxRemove <= 0) continue;
349
+ int r = 1 + (int)(rng() % maxRemove);
350
+
351
+ x[i] -= r;
352
+
353
+ // occasional second removal to escape local maxima
354
+ if ((rng() % 5) == 0) {
355
+ nonzero.clear();
356
+ for (int j = 0; j < 12; j++) if (x[j] > 0) nonzero.push_back(j);
357
+ if (!nonzero.empty()) {
358
+ int j = nonzero[(size_t)(rng() % nonzero.size())];
359
+ int maxRemove2 = min(x[j], 20);
360
+ if (maxRemove2 > 0) {
361
+ int r2 = 1 + (int)(rng() % maxRemove2);
362
+ x[j] -= r2;
363
+ }
364
+ }
365
+ }
366
+
367
+ refill_greedy(x);
368
+
369
+ long long usedM, usedL, val;
370
+ eval(x, usedM, usedL, val);
371
+ if (usedM <= M && usedL <= L && val > best.value) {
372
+ best.x = x;
373
+ best.value = val;
374
+ best.usedM = usedM;
375
+ best.usedL = usedL;
376
+ }
377
+ }
378
+
379
+ return best;
380
+ }
381
+
382
+ static uint64_t hash_input(const string& s) {
383
+ // FNV-1a 64-bit
384
+ uint64_t h = 1469598103934665603ULL;
385
+ for (unsigned char c : s) {
386
+ h ^= (uint64_t)c;
387
+ h *= 1099511628211ULL;
388
+ }
389
+ return h;
390
+ }
391
+
392
+ int main() {
393
+ ios::sync_with_stdio(false);
394
+ cin.tie(nullptr);
395
+
396
+ string input((istreambuf_iterator<char>(cin)), istreambuf_iterator<char>());
397
+ size_t i = 0;
398
+ skip_ws(input, i);
399
+ if (i >= input.size() || input[i] != '{') return 0;
400
+ i++;
401
+
402
+ vector<Item> items;
403
+ items.reserve(12);
404
+ vector<string> keyOrder;
405
+
406
+ while (true) {
407
+ skip_ws(input, i);
408
+ if (i >= input.size()) break;
409
+ if (input[i] == '}') { i++; break; }
410
+
411
+ string key = parse_string(input, i);
412
+ skip_ws(input, i);
413
+ if (i < input.size() && input[i] == ':') i++;
414
+ skip_ws(input, i);
415
+ if (i < input.size() && input[i] == '[') i++;
416
+ long long q = parse_int(input, i);
417
+ skip_ws(input, i); if (i < input.size() && input[i] == ',') i++;
418
+ long long v = parse_int(input, i);
419
+ skip_ws(input, i); if (i < input.size() && input[i] == ',') i++;
420
+ long long m = parse_int(input, i);
421
+ skip_ws(input, i); if (i < input.size() && input[i] == ',') i++;
422
+ long long l = parse_int(input, i);
423
+ skip_ws(input, i);
424
+ if (i < input.size() && input[i] == ']') i++;
425
+
426
+ Item it;
427
+ it.name = key;
428
+ it.q = (int)q;
429
+ it.v = v;
430
+ it.m = m;
431
+ it.l = l;
432
+
433
+ items.push_back(it);
434
+ keyOrder.push_back(key);
435
+
436
+ skip_ws(input, i);
437
+ if (i < input.size() && input[i] == ',') { i++; continue; }
438
+ if (i < input.size() && input[i] == '}') { i++; break; }
439
+ }
440
+
441
+ // Ensure exactly 12; if not, still proceed with min size but output what's given.
442
+ int n = (int)items.size();
443
+ if (n == 0) {
444
+ cout << "{}\n";
445
+ return 0;
446
+ }
447
+ if (n < 12) {
448
+ // pad to 12 with dummies to keep code simple
449
+ while ((int)items.size() < 12) {
450
+ Item dummy;
451
+ dummy.name = "__dummy" + to_string(items.size());
452
+ dummy.q = 0;
453
+ dummy.v = dummy.m = dummy.l = 0;
454
+ items.push_back(dummy);
455
+ keyOrder.push_back(dummy.name);
456
+ }
457
+ }
458
+ if (n > 12) {
459
+ items.resize(12);
460
+ keyOrder.resize(12);
461
+ n = 12;
462
+ }
463
+
464
+ const long long M = 20LL * 1000000LL;
465
+ const long long L = 25LL * 1000000LL;
466
+
467
+ vector<Solution> candidates;
468
+
469
+ // Greedy candidates
470
+ {
471
+ long double invM = 1.0L / (long double)M;
472
+ long double invL = 1.0L / (long double)L;
473
+ vector<pair<long double,long double>> wts = {
474
+ {1.0L, 0.0L},
475
+ {0.0L, 1.0L},
476
+ {invM, invL},
477
+ {invM, 0.5L*invL},
478
+ {invM, 2.0L*invL},
479
+ {2.0L*invM, invL},
480
+ {0.5L*invM, invL}
481
+ };
482
+ uint64_t h = hash_input(input);
483
+ mt19937_64 rng(h ^ 0xA5A5A5A5A5A5A5A5ULL);
484
+ for (int t = 0; t < 6; t++) {
485
+ long double a = (long double)(rng() % 5000) / 1000.0L; // [0,5)
486
+ long double b = (long double)(rng() % 5000) / 1000.0L; // [0,5)
487
+ if (a < 0.05L && b < 0.05L) { a = invM; b = invL; }
488
+ wts.push_back({a*invM, b*invL});
489
+ }
490
+ for (auto [a,b] : wts) candidates.push_back(greedy(items, M, L, a, b));
491
+ }
492
+
493
+ // Beam search candidates
494
+ vector<WeightRun> runs;
495
+ runs.push_back({1,1,true});
496
+ runs.push_back({0,1,true});
497
+ runs.push_back({1,4,true});
498
+ runs.push_back({1,2,true});
499
+ runs.push_back({2,1,true});
500
+ runs.push_back({4,1,true});
501
+ runs.push_back({8,1,true});
502
+ runs.push_back({1,4,false});
503
+ runs.push_back({1,2,false});
504
+ runs.push_back({2,1,false});
505
+ {
506
+ uint64_t h = hash_input(input);
507
+ mt19937_64 rng(h ^ 0x1234567890ABCDEFULL);
508
+ for (int t = 0; t < 4; t++) {
509
+ long long p = 1 + (long long)(rng() % 6);
510
+ long long q = 1 + (long long)(rng() % 6);
511
+ bool vol = (rng() & 1);
512
+ runs.push_back({p,q,vol});
513
+ }
514
+ }
515
+
516
+ int BEAM_W = 2500;
517
+ for (auto &wr : runs) {
518
+ candidates.push_back(beam_search(items, M, L, wr, BEAM_W));
519
+ }
520
+
521
+ // Choose best candidate
522
+ Solution best;
523
+ best.value = -1;
524
+ for (auto &s : candidates) {
525
+ auto used = compute_used(items, s.x);
526
+ s.usedM = used.first;
527
+ s.usedL = used.second;
528
+ if (s.usedM <= M && s.usedL <= L && s.value > best.value) best = s;
529
+ }
530
+
531
+ // Local improvement on best
532
+ {
533
+ uint64_t seed = hash_input(input) ^ 0x9E3779B97F4A7C15ULL;
534
+ best = local_improve(items, M, L, best, seed, 6000);
535
+ }
536
+
537
+ // Output JSON in original key order (first n keys)
538
+ cout << "{\n";
539
+ for (int k = 0; k < n; k++) {
540
+ cout << " \"" << items[k].name << "\": " << best.x[k];
541
+ if (k + 1 < n) cout << ",\n";
542
+ else cout << "\n";
543
+ }
544
+ cout << "}\n";
545
+ return 0;
546
+ }
docker_space/frontier_cs_1/examples/gpt5.2_1.cpp ADDED
@@ -0,0 +1,437 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <bits/stdc++.h>
2
+ using namespace std;
3
+
4
+ struct Item {
5
+ string name;
6
+ int q;
7
+ long long v, m, l;
8
+ };
9
+
10
+ struct Solution {
11
+ vector<long long> x;
12
+ long long mass = 0, vol = 0, val = 0;
13
+ };
14
+
15
+ static const long long CAP_M = 20LL * 1000000LL;
16
+ static const long long CAP_L = 25LL * 1000000LL;
17
+
18
+ struct Parser {
19
+ string s;
20
+ size_t i = 0;
21
+
22
+ explicit Parser(string in) : s(std::move(in)), i(0) {}
23
+
24
+ void skipWs() {
25
+ while (i < s.size() && (s[i] == ' ' || s[i] == '\n' || s[i] == '\r' || s[i] == '\t')) i++;
26
+ }
27
+
28
+ void expect(char c) {
29
+ skipWs();
30
+ if (i >= s.size() || s[i] != c) {
31
+ // invalid input, but we assume valid per problem statement
32
+ return;
33
+ }
34
+ i++;
35
+ }
36
+
37
+ string parseString() {
38
+ skipWs();
39
+ expect('"');
40
+ string out;
41
+ while (i < s.size() && s[i] != '"') {
42
+ out.push_back(s[i]);
43
+ i++;
44
+ }
45
+ expect('"');
46
+ return out;
47
+ }
48
+
49
+ long long parseInt() {
50
+ skipWs();
51
+ long long sign = 1;
52
+ if (i < s.size() && s[i] == '-') { sign = -1; i++; }
53
+ long long x = 0;
54
+ while (i < s.size() && isdigit((unsigned char)s[i])) {
55
+ x = x * 10 + (s[i] - '0');
56
+ i++;
57
+ }
58
+ return x * sign;
59
+ }
60
+ };
61
+
62
+ static inline long long clamp_ll(long long x, long long lo, long long hi) {
63
+ return max(lo, min(hi, x));
64
+ }
65
+
66
+ static inline long double densityNormSum(const Item& it, long double alpha) {
67
+ long double dm = (long double)it.m / (long double)CAP_M;
68
+ long double dl = (long double)it.l / (long double)CAP_L;
69
+ long double denom = alpha * dm + (1.0L - alpha) * dl;
70
+ if (denom <= 0) return 0;
71
+ return (long double)it.v / denom;
72
+ }
73
+
74
+ static inline long double densityNormMax(const Item& it) {
75
+ long double dm = (long double)it.m / (long double)CAP_M;
76
+ long double dl = (long double)it.l / (long double)CAP_L;
77
+ long double denom = max(dm, dl);
78
+ if (denom <= 0) return 0;
79
+ return (long double)it.v / denom;
80
+ }
81
+
82
+ static inline long double densitySumRaw(const Item& it, long double lambda) {
83
+ long double denom = (long double)it.m + lambda * (long double)it.l;
84
+ if (denom <= 0) return 0;
85
+ return (long double)it.v / denom;
86
+ }
87
+
88
+ static Solution evalSolution(const vector<Item>& items, const vector<long long>& x) {
89
+ Solution sol;
90
+ sol.x = x;
91
+ sol.mass = sol.vol = sol.val = 0;
92
+ for (size_t k = 0; k < items.size(); k++) {
93
+ sol.mass += items[k].m * sol.x[k];
94
+ sol.vol += items[k].l * sol.x[k];
95
+ sol.val += items[k].v * sol.x[k];
96
+ }
97
+ return sol;
98
+ }
99
+
100
+ static void refillWithOrder(const vector<Item>& items, Solution& sol, const vector<int>& order) {
101
+ for (int idx : order) {
102
+ const auto& it = items[idx];
103
+ if (sol.x[idx] >= it.q) continue;
104
+ long long remM = CAP_M - sol.mass;
105
+ long long remL = CAP_L - sol.vol;
106
+ if (remM <= 0 || remL <= 0) continue;
107
+ long long add = it.q - sol.x[idx];
108
+ add = min(add, remM / it.m);
109
+ add = min(add, remL / it.l);
110
+ if (add <= 0) continue;
111
+ sol.x[idx] += add;
112
+ sol.mass += it.m * add;
113
+ sol.vol += it.l * add;
114
+ sol.val += it.v * add;
115
+ }
116
+ }
117
+
118
+ static void greedyFillFromEmpty(const vector<Item>& items, Solution& sol, const vector<int>& order) {
119
+ sol.x.assign(items.size(), 0);
120
+ sol.mass = sol.vol = sol.val = 0;
121
+ refillWithOrder(items, sol, order);
122
+ }
123
+
124
+ static void repairFeasible(const vector<Item>& items, Solution& sol) {
125
+ if (sol.mass <= CAP_M && sol.vol <= CAP_L) return;
126
+
127
+ int n = (int)items.size();
128
+ vector<int> idxs(n);
129
+ iota(idxs.begin(), idxs.end(), 0);
130
+
131
+ auto dens = [&](int i) -> long double {
132
+ return densityNormSum(items[i], 0.5L);
133
+ };
134
+
135
+ // Remove lowest density items in bulk until feasible.
136
+ for (int step = 0; step < 1000 && (sol.mass > CAP_M || sol.vol > CAP_L); step++) {
137
+ int best = -1;
138
+ long double bestD = 1e300L;
139
+ for (int i = 0; i < n; i++) {
140
+ if (sol.x[i] <= 0) continue;
141
+ long double d = dens(i);
142
+ if (d < bestD) { bestD = d; best = i; }
143
+ }
144
+ if (best < 0) break;
145
+
146
+ long long overM = max(0LL, sol.mass - CAP_M);
147
+ long long overL = max(0LL, sol.vol - CAP_L);
148
+ const auto& it = items[best];
149
+
150
+ long long need = 1;
151
+ if (overM > 0) need = max(need, (overM + it.m - 1) / it.m);
152
+ if (overL > 0) need = max(need, (overL + it.l - 1) / it.l);
153
+ need = min(need, sol.x[best]);
154
+ if (need <= 0) need = 1;
155
+
156
+ sol.x[best] -= need;
157
+ sol.mass -= it.m * need;
158
+ sol.vol -= it.l * need;
159
+ sol.val -= it.v * need;
160
+ }
161
+
162
+ // Final safety: remove one by one if still infeasible.
163
+ for (int step = 0; step < 100000 && (sol.mass > CAP_M || sol.vol > CAP_L); step++) {
164
+ int best = -1;
165
+ long double bestD = 1e300L;
166
+ for (int i = 0; i < (int)items.size(); i++) {
167
+ if (sol.x[i] <= 0) continue;
168
+ long double d = densityNormSum(items[i], 0.5L);
169
+ if (d < bestD) { bestD = d; best = i; }
170
+ }
171
+ if (best < 0) break;
172
+ sol.x[best]--;
173
+ sol.mass -= items[best].m;
174
+ sol.vol -= items[best].l;
175
+ sol.val -= items[best].v;
176
+ }
177
+
178
+ if (sol.mass < 0) sol.mass = 0;
179
+ if (sol.vol < 0) sol.vol = 0;
180
+ if (sol.val < 0) sol.val = 0;
181
+ }
182
+
183
+ static bool pairOptimizeExact(const vector<Item>& items, Solution& sol, int i, int j) {
184
+ if (i == j) return false;
185
+ const auto& A = items[i];
186
+ const auto& B = items[j];
187
+
188
+ long long xi = sol.x[i], xj = sol.x[j];
189
+ long long mass_others = sol.mass - A.m * xi - B.m * xj;
190
+ long long vol_others = sol.vol - A.l * xi - B.l * xj;
191
+ long long val_others = sol.val - A.v * xi - B.v * xj;
192
+
193
+ long long Mrem = CAP_M - mass_others;
194
+ long long Lrem = CAP_L - vol_others;
195
+ if (Mrem < 0 || Lrem < 0) return false;
196
+
197
+ long long aUpper = min<long long>(A.q, min(Mrem / A.m, Lrem / A.l));
198
+ long long bUpper = min<long long>(B.q, min(Mrem / B.m, Lrem / B.l));
199
+
200
+ long long curPairVal = A.v * xi + B.v * xj;
201
+ long long curPairMass = A.m * xi + B.m * xj;
202
+ long long curPairVol = A.l * xi + B.l * xj;
203
+
204
+ long long bestA = xi, bestB = xj;
205
+ long long bestPairVal = curPairVal;
206
+ long long bestPairUsed = curPairMass + curPairVol;
207
+
208
+ auto consider = [&](long long a, long long b) {
209
+ if (a < 0 || b < 0) return;
210
+ if (a > A.q || b > B.q) return;
211
+ long long mm = A.m * a + B.m * b;
212
+ long long ll = A.l * a + B.l * b;
213
+ if (mm > Mrem || ll > Lrem) return;
214
+ long long vv = A.v * a + B.v * b;
215
+ long long used = mm + ll;
216
+ if (vv > bestPairVal || (vv == bestPairVal && used < bestPairUsed)) {
217
+ bestPairVal = vv;
218
+ bestPairUsed = used;
219
+ bestA = a;
220
+ bestB = b;
221
+ }
222
+ };
223
+
224
+ if (aUpper <= bUpper) {
225
+ for (long long a = 0; a <= aUpper; a++) {
226
+ long long Mleft = Mrem - A.m * a;
227
+ long long Lleft = Lrem - A.l * a;
228
+ if (Mleft < 0 || Lleft < 0) break;
229
+ long long b = min<long long>(B.q, min(Mleft / B.m, Lleft / B.l));
230
+ consider(a, b);
231
+ }
232
+ } else {
233
+ for (long long b = 0; b <= bUpper; b++) {
234
+ long long Mleft = Mrem - B.m * b;
235
+ long long Lleft = Lrem - B.l * b;
236
+ if (Mleft < 0 || Lleft < 0) break;
237
+ long long a = min<long long>(A.q, min(Mleft / A.m, Lleft / A.l));
238
+ consider(a, b);
239
+ }
240
+ }
241
+
242
+ if (bestA == xi && bestB == xj) return false;
243
+
244
+ // Apply
245
+ sol.x[i] = bestA;
246
+ sol.x[j] = bestB;
247
+ sol.mass = mass_others + A.m * bestA + B.m * bestB;
248
+ sol.vol = vol_others + A.l * bestA + B.l * bestB;
249
+ sol.val = val_others + A.v * bestA + B.v * bestB;
250
+
251
+ return true;
252
+ }
253
+
254
+ static void improveSolution(const vector<Item>& items, Solution& sol, const vector<int>& refillOrder, mt19937_64& rng, int maxRounds) {
255
+ repairFeasible(items, sol);
256
+ refillWithOrder(items, sol, refillOrder);
257
+ repairFeasible(items, sol);
258
+
259
+ int n = (int)items.size();
260
+ vector<pair<int,int>> pairs;
261
+ pairs.reserve(n*(n-1)/2);
262
+ for (int i = 0; i < n; i++)
263
+ for (int j = i+1; j < n; j++)
264
+ pairs.emplace_back(i,j);
265
+
266
+ for (int round = 0; round < maxRounds; round++) {
267
+ bool changed = false;
268
+ shuffle(pairs.begin(), pairs.end(), rng);
269
+ for (auto [i,j] : pairs) {
270
+ changed |= pairOptimizeExact(items, sol, i, j);
271
+ }
272
+ long long oldVal = sol.val;
273
+ long long oldMass = sol.mass, oldVol = sol.vol;
274
+ refillWithOrder(items, sol, refillOrder);
275
+ if (sol.val != oldVal || sol.mass != oldMass || sol.vol != oldVol) changed = true;
276
+ if (!changed) break;
277
+ }
278
+ repairFeasible(items, sol);
279
+ }
280
+
281
+ static vector<int> makeOrder(const vector<Item>& items, function<long double(const Item&)> scoreFn) {
282
+ int n = (int)items.size();
283
+ vector<int> order(n);
284
+ iota(order.begin(), order.end(), 0);
285
+ stable_sort(order.begin(), order.end(), [&](int a, int b){
286
+ long double sa = scoreFn(items[a]);
287
+ long double sb = scoreFn(items[b]);
288
+ if (sa != sb) return sa > sb;
289
+ return items[a].v > items[b].v;
290
+ });
291
+ return order;
292
+ }
293
+
294
+ int main() {
295
+ ios::sync_with_stdio(false);
296
+ cin.tie(nullptr);
297
+
298
+ string input, line;
299
+ while (getline(cin, line)) {
300
+ input += line;
301
+ input.push_back('\n');
302
+ }
303
+
304
+ Parser p(input);
305
+ p.skipWs();
306
+ p.expect('{');
307
+
308
+ vector<Item> items;
309
+ vector<string> keyOrder;
310
+
311
+ while (true) {
312
+ p.skipWs();
313
+ if (p.i < p.s.size() && p.s[p.i] == '}') { p.i++; break; }
314
+ string key = p.parseString();
315
+ keyOrder.push_back(key);
316
+ p.skipWs();
317
+ p.expect(':');
318
+ p.skipWs();
319
+ p.expect('[');
320
+ long long q = p.parseInt();
321
+ p.skipWs(); p.expect(',');
322
+ long long v = p.parseInt();
323
+ p.skipWs(); p.expect(',');
324
+ long long m = p.parseInt();
325
+ p.skipWs(); p.expect(',');
326
+ long long l = p.parseInt();
327
+ p.skipWs();
328
+ p.expect(']');
329
+ items.push_back(Item{key, (int)q, v, m, l});
330
+ p.skipWs();
331
+ if (p.i < p.s.size() && p.s[p.i] == ',') { p.i++; continue; }
332
+ if (p.i < p.s.size() && p.s[p.i] == '}') { p.i++; break; }
333
+ }
334
+
335
+ int n = (int)items.size();
336
+ // Safety if input malformed; but statement guarantees exactly 12.
337
+ if (n == 0) {
338
+ cout << "{\n}\n";
339
+ return 0;
340
+ }
341
+
342
+ mt19937_64 rng(0xC0FFEE123456789ULL);
343
+
344
+ // Precompute a few orders
345
+ vector<vector<int>> orders;
346
+ vector<long double> alphas = {0.0L, 0.2L, 0.4L, 0.5L, 0.6L, 0.8L, 1.0L};
347
+ for (auto a : alphas) {
348
+ orders.push_back(makeOrder(items, [a](const Item& it){ return densityNormSum(it, a); }));
349
+ }
350
+ orders.push_back(makeOrder(items, [](const Item& it){ return densityNormMax(it); }));
351
+ orders.push_back(makeOrder(items, [](const Item& it){
352
+ return (it.m > 0) ? (long double)it.v / (long double)it.m : 0.0L;
353
+ }));
354
+ orders.push_back(makeOrder(items, [](const Item& it){
355
+ return (it.l > 0) ? (long double)it.v / (long double)it.l : 0.0L;
356
+ }));
357
+ orders.push_back(makeOrder(items, [](const Item& it){ return (long double)it.v; }));
358
+ orders.push_back(makeOrder(items, [](const Item& it){
359
+ return (long double)it.v / ( (long double)it.m + (long double)it.l );
360
+ }));
361
+ vector<long double> lambdas = {0.0L, 0.01L, 0.05L, 0.1L, 0.2L, 0.5L, 1.0L, 2.0L, 5.0L, 10.0L};
362
+ for (auto lam : lambdas) {
363
+ orders.push_back(makeOrder(items, [lam](const Item& it){ return densitySumRaw(it, lam); }));
364
+ }
365
+
366
+ // Baseline best: try each order
367
+ Solution best;
368
+ best.x.assign(n, 0);
369
+ best.mass = best.vol = best.val = 0;
370
+
371
+ for (const auto& ord : orders) {
372
+ Solution sol;
373
+ greedyFillFromEmpty(items, sol, ord);
374
+ improveSolution(items, sol, ord, rng, 4);
375
+ if (sol.val > best.val) best = sol;
376
+ }
377
+
378
+ // Randomized multi-start / perturbation
379
+ int ITER = 160;
380
+ for (int t = 0; t < ITER; t++) {
381
+ Solution sol = best;
382
+
383
+ if (t % 6 == 0) {
384
+ // start from empty with random order
385
+ vector<int> ord(n);
386
+ iota(ord.begin(), ord.end(), 0);
387
+ shuffle(ord.begin(), ord.end(), rng);
388
+ greedyFillFromEmpty(items, sol, ord);
389
+ improveSolution(items, sol, ord, rng, 3);
390
+ } else {
391
+ // perturb best
392
+ for (int i = 0; i < n; i++) {
393
+ if (sol.x[i] == 0) continue;
394
+ uint64_t r = rng() % 100;
395
+ if (r < 8) sol.x[i] = 0;
396
+ else if (r < 24) sol.x[i] = sol.x[i] / 4;
397
+ else if (r < 48) sol.x[i] = sol.x[i] / 2;
398
+ else if (r < 64) sol.x[i] = (sol.x[i] * 3) / 4;
399
+ }
400
+ sol = evalSolution(items, sol.x);
401
+ repairFeasible(items, sol);
402
+
403
+ // choose a random alpha-based order to refill
404
+ long double a = (long double)(rng() % 1000) / 1000.0L;
405
+ auto ord = makeOrder(items, [a](const Item& it){ return densityNormSum(it, a); });
406
+ refillWithOrder(items, sol, ord);
407
+ improveSolution(items, sol, ord, rng, 3);
408
+ }
409
+
410
+ if (sol.val > best.val) best = sol;
411
+ }
412
+
413
+ // Final repair and slight refill using best normalized order
414
+ auto finalOrd = makeOrder(items, [](const Item& it){ return densityNormSum(it, 0.5L); });
415
+ repairFeasible(items, best);
416
+ refillWithOrder(items, best, finalOrd);
417
+ repairFeasible(items, best);
418
+
419
+ // Output JSON with same keys as input in the same order.
420
+ // Build mapping from name to count from items order.
421
+ unordered_map<string, long long> out;
422
+ out.reserve(n * 2);
423
+ for (int i = 0; i < n; i++) out[items[i].name] = best.x[i];
424
+
425
+ cout << "{\n";
426
+ for (int k = 0; k < (int)keyOrder.size(); k++) {
427
+ const string& key = keyOrder[k];
428
+ long long cnt = 0;
429
+ auto it = out.find(key);
430
+ if (it != out.end()) cnt = it->second;
431
+ cout << " \"" << key << "\": " << cnt;
432
+ if (k + 1 < (int)keyOrder.size()) cout << ",";
433
+ cout << "\n";
434
+ }
435
+ cout << "}\n";
436
+ return 0;
437
+ }