Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .claude/skills/dataclaw/SKILL.md +103 -0
- docker_space/frontier_cs_0_polyomino/0/.claude/settings.local.json +8 -0
- docker_space/frontier_cs_0_polyomino/0/INSTRUCTION.md +89 -0
- docker_space/frontier_cs_0_polyomino/0/best/evolution.log +24 -0
- docker_space/frontier_cs_0_polyomino/0/best/score.txt +12 -0
- docker_space/frontier_cs_0_polyomino/0/best/solution.cpp +337 -0
- docker_space/frontier_cs_0_polyomino/0/chk.cc +152 -0
- docker_space/frontier_cs_0_polyomino/0/config.yaml +12 -0
- docker_space/frontier_cs_0_polyomino/0/evaluate.md +76 -0
- docker_space/frontier_cs_0_polyomino/0/examples/gpt5.cpp +271 -0
- docker_space/frontier_cs_0_polyomino/0/examples/reference.cpp +297 -0
- docker_space/frontier_cs_0_polyomino/0/statement.txt +107 -0
- docker_space/frontier_cs_0_polyomino_ev2/.claude/settings.local.json +8 -0
- docker_space/frontier_cs_0_polyomino_ev2/best/best.cpp +535 -0
- docker_space/frontier_cs_0_polyomino_ev2/best/scores.txt +14 -0
- docker_space/frontier_cs_0_polyomino_ev2/examples/gpt5.cpp +271 -0
- docker_space/frontier_cs_0_polyomino_ev2/examples/reference.cpp +297 -0
- docker_space/frontier_cs_0_polyomino_ev2/logs/evolution.log +48 -0
- docker_space/frontier_cs_0_polyomino_ev2/logs/gen_0.cpp +297 -0
- docker_space/frontier_cs_0_polyomino_ev2/logs/gen_1.cpp +366 -0
- docker_space/frontier_cs_0_polyomino_ev2/logs/gen_18.cpp +515 -0
- docker_space/frontier_cs_0_polyomino_ev2/logs/gen_20.cpp +515 -0
- docker_space/frontier_cs_0_polyomino_ev2/logs/gen_26.cpp +516 -0
- docker_space/frontier_cs_0_polyomino_ev2/logs/gen_27.cpp +517 -0
- docker_space/frontier_cs_0_polyomino_ev2/logs/gen_28.cpp +517 -0
- docker_space/frontier_cs_0_polyomino_ev2/logs/gen_3.cpp +395 -0
- docker_space/frontier_cs_0_polyomino_ev2/logs/gen_30.cpp +517 -0
- docker_space/frontier_cs_0_polyomino_ev2/logs/gen_33.cpp +535 -0
- docker_space/frontier_cs_0_polyomino_ev2/logs/gen_5.cpp +399 -0
- docker_space/frontier_cs_1/examples/deepseekreasoner.cpp +232 -0
- docker_space/frontier_cs_1/examples/deepseekreasoner_1.cpp +174 -0
- docker_space/frontier_cs_1/examples/deepseekreasoner_2.cpp +265 -0
- docker_space/frontier_cs_1/examples/deepseekreasoner_3.cpp +179 -0
- docker_space/frontier_cs_1/examples/deepseekreasoner_4.cpp +300 -0
- docker_space/frontier_cs_1/examples/gemini2.5pro.cpp +234 -0
- docker_space/frontier_cs_1/examples/gemini2.5pro_2.cpp +185 -0
- docker_space/frontier_cs_1/examples/gemini2.5pro_3.cpp +184 -0
- docker_space/frontier_cs_1/examples/gemini2.5pro_4.cpp +203 -0
- docker_space/frontier_cs_1/examples/gemini3pro.cpp +217 -0
- docker_space/frontier_cs_1/examples/gemini3pro_1.cpp +287 -0
- docker_space/frontier_cs_1/examples/gemini3pro_2.cpp +288 -0
- docker_space/frontier_cs_1/examples/gemini3pro_3.cpp +251 -0
- docker_space/frontier_cs_1/examples/gemini3pro_4.cpp +284 -0
- docker_space/frontier_cs_1/examples/gpt5.1.cpp +334 -0
- docker_space/frontier_cs_1/examples/gpt5.1_1.cpp +304 -0
- docker_space/frontier_cs_1/examples/gpt5.1_2.cpp +302 -0
- docker_space/frontier_cs_1/examples/gpt5.1_3.cpp +353 -0
- docker_space/frontier_cs_1/examples/gpt5.1_4.cpp +308 -0
- docker_space/frontier_cs_1/examples/gpt5.2.cpp +546 -0
- 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 |
+
}
|