feat(tests): fixtures
This commit is contained in:
parent
c143600c5b
commit
4fac6c8019
7 changed files with 3750 additions and 1823 deletions
|
|
@ -19,7 +19,7 @@ from .models import (
|
|||
)
|
||||
|
||||
BASE_URL = "https://cses.fi"
|
||||
INDEX_PATH = "/problemset/list"
|
||||
INDEX_PATH = "/problemset"
|
||||
TASK_PATH = "/problemset/task/{id}"
|
||||
HEADERS = {
|
||||
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
import asyncio
|
||||
import importlib.util
|
||||
import io
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from types import ModuleType
|
||||
from types import SimpleNamespace
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
import requests
|
||||
from scrapling import fetchers
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
FIX = Path(__file__).resolve().parent / "fixtures"
|
||||
|
|
@ -20,12 +25,12 @@ def fixture_text():
|
|||
return _load
|
||||
|
||||
|
||||
def _load_scraper_module(module_path: Path, module_name: str) -> ModuleType:
|
||||
def _load_scraper_module(module_path: Path, module_name: str):
|
||||
spec = importlib.util.spec_from_file_location(
|
||||
f"scrapers.{module_name}", module_path
|
||||
)
|
||||
if spec is None or spec.loader is None:
|
||||
raise ImportError(f"Could not load spec for {module_name} from {module_path}")
|
||||
raise ImportError(f"Cannot load module {module_name}")
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
sys.modules[f"scrapers.{module_name}"] = module
|
||||
spec.loader.exec_module(module)
|
||||
|
|
@ -33,8 +38,6 @@ def _load_scraper_module(module_path: Path, module_name: str) -> ModuleType:
|
|||
|
||||
|
||||
def _capture_stdout(coro):
|
||||
import asyncio
|
||||
|
||||
buf = io.StringIO()
|
||||
old = sys.stdout
|
||||
sys.stdout = buf
|
||||
|
|
@ -49,12 +52,26 @@ def _capture_stdout(coro):
|
|||
@pytest.fixture
|
||||
def run_scraper_offline(fixture_text):
|
||||
def _router_cses(*, path: str | None = None, url: str | None = None) -> str:
|
||||
if path == "/problemset/list":
|
||||
if not path and not url:
|
||||
raise AssertionError("CSES expects path or url")
|
||||
|
||||
target = path or url
|
||||
if target is None:
|
||||
raise AssertionError(f"No target for CSES (path={path!r}, url={url!r})")
|
||||
|
||||
if target.startswith("https://cses.fi"):
|
||||
target = target.removeprefix("https://cses.fi")
|
||||
|
||||
if target.strip("/") == "problemset":
|
||||
return fixture_text("cses_contests.html")
|
||||
if path and path.startswith("/problemset/task/"):
|
||||
pid = path.rsplit("/", 1)[-1]
|
||||
|
||||
if target.startswith("/problemset/task/") or target.startswith(
|
||||
"problemset/task/"
|
||||
):
|
||||
pid = target.rstrip("/").split("/")[-1]
|
||||
return fixture_text(f"cses_task_{pid}.html")
|
||||
raise AssertionError(f"No fixture for CSES path={path!r}")
|
||||
|
||||
raise AssertionError(f"No fixture for CSES path={path!r} url={url!r}")
|
||||
|
||||
def _router_atcoder(*, path: str | None = None, url: str | None = None) -> str:
|
||||
if not url:
|
||||
|
|
@ -71,6 +88,9 @@ def run_scraper_offline(fixture_text):
|
|||
def _router_codeforces(*, path: str | None = None, url: str | None = None) -> str:
|
||||
if not url:
|
||||
raise AssertionError("Codeforces expects url routing")
|
||||
if "/contest/" in url and url.endswith("/problems"):
|
||||
contest_id = url.rstrip("/").split("/")[-2]
|
||||
return fixture_text(f"codeforces_{contest_id}_problems.html")
|
||||
if "/contests" in url and "/problem/" not in url:
|
||||
return fixture_text("codeforces_contests.html")
|
||||
if "/problem/" in url:
|
||||
|
|
@ -81,58 +101,99 @@ def run_scraper_offline(fixture_text):
|
|||
parts = url.rstrip("/").split("/")
|
||||
contest_id, index = parts[-2], parts[-1]
|
||||
return fixture_text(f"codeforces_{contest_id}_{index}.html")
|
||||
|
||||
raise AssertionError(f"No fixture for Codeforces url={url!r}")
|
||||
|
||||
def _make_offline_fetches(scraper_name: str):
|
||||
if scraper_name == "cses":
|
||||
match scraper_name:
|
||||
case "cses":
|
||||
|
||||
def __offline_fetch_text(client, path: str) -> str:
|
||||
return _router_cses(path=path)
|
||||
async def __offline_fetch_text(client, path: str, **kwargs):
|
||||
html = _router_cses(path=path)
|
||||
return SimpleNamespace(
|
||||
text=html,
|
||||
status_code=200,
|
||||
raise_for_status=lambda: None,
|
||||
)
|
||||
|
||||
return {
|
||||
"__offline_fetch_text": __offline_fetch_text,
|
||||
"__offline_fetch_sync": lambda url: (_ for _ in ()).throw(
|
||||
AssertionError("CSES doesn't use _fetch")
|
||||
),
|
||||
"__offline_fetch_async": lambda client, url: (_ for _ in ()).throw(
|
||||
AssertionError("CSES doesn't use _get_async")
|
||||
),
|
||||
}
|
||||
if scraper_name == "atcoder":
|
||||
return {
|
||||
"__offline_fetch_text": __offline_fetch_text,
|
||||
}
|
||||
|
||||
async def __offline_fetch_async(client, url: str) -> str:
|
||||
return _router_atcoder(url=url)
|
||||
case "atcoder":
|
||||
|
||||
def __offline_fetch_sync(url: str) -> str:
|
||||
return _router_atcoder(url=url)
|
||||
def __offline_fetch(url: str, *args, **kwargs):
|
||||
html = _router_atcoder(url=url)
|
||||
return html
|
||||
|
||||
return {
|
||||
"__offline_fetch_text": lambda client, path: (_ for _ in ()).throw(
|
||||
AssertionError("AtCoder doesn't use fetch_text")
|
||||
),
|
||||
"__offline_fetch_sync": __offline_fetch_sync,
|
||||
"__offline_fetch_async": __offline_fetch_async,
|
||||
}
|
||||
if scraper_name == "codeforces":
|
||||
async def __offline_get_async(client, url: str, **kwargs):
|
||||
return _router_atcoder(url=url)
|
||||
|
||||
def __offline_fetch_sync(url: str) -> str:
|
||||
return _router_codeforces(url=url)
|
||||
return {
|
||||
"_fetch": __offline_fetch,
|
||||
"_get_async": __offline_get_async,
|
||||
}
|
||||
|
||||
return {
|
||||
"__offline_fetch_text": lambda client, path: (_ for _ in ()).throw(
|
||||
AssertionError("Codeforces doesn't use fetch_text")
|
||||
),
|
||||
"__offline_fetch_sync": __offline_fetch_sync,
|
||||
"__offline_fetch_async": lambda client, url: (_ for _ in ()).throw(
|
||||
AssertionError("Codeforces doesn't use _get_async")
|
||||
),
|
||||
}
|
||||
raise AssertionError(f"Unknown scraper: {scraper_name}")
|
||||
case "codeforces":
|
||||
|
||||
class MockPage:
|
||||
def __init__(self, html: str):
|
||||
self.html_content = html
|
||||
|
||||
def _mock_stealthy_fetch(url: str, **kwargs):
|
||||
return MockPage(_router_codeforces(url=url))
|
||||
|
||||
def _mock_requests_get(url: str, **kwargs):
|
||||
if "api/contest.list" in url:
|
||||
data = {
|
||||
"status": "OK",
|
||||
"result": [
|
||||
{
|
||||
"id": 1550,
|
||||
"name": "Educational Codeforces Round 155 (Rated for Div. 2)",
|
||||
"phase": "FINISHED",
|
||||
},
|
||||
{
|
||||
"id": 1000,
|
||||
"name": "Codeforces Round #1000",
|
||||
"phase": "FINISHED",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
class R:
|
||||
def json(self_inner):
|
||||
return data
|
||||
|
||||
def raise_for_status(self_inner):
|
||||
return None
|
||||
|
||||
return R()
|
||||
raise AssertionError(f"Unexpected requests.get call: {url}")
|
||||
|
||||
return {
|
||||
"StealthyFetcher.fetch": _mock_stealthy_fetch,
|
||||
"requests.get": _mock_requests_get,
|
||||
}
|
||||
|
||||
case _:
|
||||
raise AssertionError(f"Unknown scraper: {scraper_name}")
|
||||
|
||||
def _run(scraper_name: str, mode: str, *args: str):
|
||||
mod_path = ROOT / "scrapers" / f"{scraper_name}.py"
|
||||
ns = _load_scraper_module(mod_path, scraper_name)
|
||||
main_async = getattr(ns, "main_async", None)
|
||||
offline_fetches = _make_offline_fetches(scraper_name)
|
||||
|
||||
if scraper_name == "codeforces":
|
||||
fetchers.stealthyfetcher.fetch = offline_fetches["stealthyfetcher.fetch"] # type: ignore
|
||||
requests.get = offline_fetches["requests.get"]
|
||||
elif scraper_name == "atcoder":
|
||||
ns._fetch = offline_fetches["_fetch"]
|
||||
ns._get_async = offline_fetches["_get_async"]
|
||||
elif scraper_name == "cses":
|
||||
httpx.asyncclient.get = offline_fetches["__offline_fetch_text"] # type: ignore
|
||||
|
||||
main_async = getattr(ns, "main_async")
|
||||
assert callable(main_async), f"main_async not found in {scraper_name}"
|
||||
|
||||
argv = [str(mod_path), mode, *args]
|
||||
|
|
@ -143,14 +204,9 @@ def run_scraper_offline(fixture_text):
|
|||
finally:
|
||||
sys.argv = old_argv
|
||||
|
||||
json_lines = []
|
||||
json_lines: list[Any] = []
|
||||
for line in (l for l in out.splitlines() if l.strip()):
|
||||
try:
|
||||
json_lines.append(json.loads(line))
|
||||
except json.JSONDecodeError as e:
|
||||
raise AssertionError(
|
||||
f"Invalid JSON from {scraper_name} {mode}: {line}"
|
||||
) from e
|
||||
json_lines.append(json.loads(line))
|
||||
return rc, json_lines
|
||||
|
||||
return _run
|
||||
|
|
|
|||
1483
tests/fixtures/atcoder_task_abc100_a.html
vendored
1483
tests/fixtures/atcoder_task_abc100_a.html
vendored
File diff suppressed because it is too large
Load diff
1483
tests/fixtures/atcoder_task_abc100_b.html
vendored
1483
tests/fixtures/atcoder_task_abc100_b.html
vendored
File diff suppressed because it is too large
Load diff
618
tests/fixtures/atcoder_task_abc100_c.html
vendored
Normal file
618
tests/fixtures/atcoder_task_abc100_c.html
vendored
Normal file
|
|
@ -0,0 +1,618 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>C - *3 or /2</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta http-equiv="Content-Language" content="en">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="google-site-verification" content="nXGC_JxO0yoP1qBzMnYD_xgufO6leSLw1kyNo2HZltM" />
|
||||
|
||||
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-RC512FD18N"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('set', 'user_properties', {
|
||||
|
||||
'login_status': 'logged_out',
|
||||
|
||||
});
|
||||
gtag('config', 'G-RC512FD18N');
|
||||
</script>
|
||||
|
||||
|
||||
<meta name="description" content="AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.">
|
||||
<meta name="author" content="AtCoder Inc.">
|
||||
|
||||
<meta property="og:site_name" content="AtCoder">
|
||||
|
||||
<meta property="og:title" content="C - *3 or /2" />
|
||||
<meta property="og:description" content="AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online." />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://atcoder.jp/contests/abc100/tasks/abc100_c" />
|
||||
<meta property="og:image" content="https://img.atcoder.jp/assets/atcoder.png" />
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@atcoder" />
|
||||
|
||||
<meta property="twitter:title" content="C - *3 or /2" />
|
||||
|
||||
<link href="//fonts.googleapis.com/css?family=Lato:400,700" rel="stylesheet" type="text/css">
|
||||
<link rel="stylesheet" type="text/css" href="//img.atcoder.jp/public/6372bb3/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="//img.atcoder.jp/public/6372bb3/css/base.css">
|
||||
<link rel="shortcut icon" type="image/png" href="//img.atcoder.jp/assets/favicon.png">
|
||||
<link rel="apple-touch-icon" href="//img.atcoder.jp/assets/atcoder.png">
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/lib/jquery-1.9.1.min.js"></script>
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/lib/bootstrap.min.js"></script>
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/cdn/js.cookie.min.js"></script>
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/cdn/moment.min.js"></script>
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/cdn/moment_js-ja.js"></script>
|
||||
<script>
|
||||
var LANG = "en";
|
||||
var userScreenName = "";
|
||||
var csrfToken = "KwoiS7wTPLvccvgUDoQZ6H++fkjXMCchJrW6/YFqOJM="
|
||||
</script>
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/utils.js"></script>
|
||||
|
||||
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/contest.js"></script>
|
||||
<link href="//img.atcoder.jp/public/6372bb3/css/contest.css" rel="stylesheet" />
|
||||
<script>
|
||||
var contestScreenName = "abc100";
|
||||
var remainingText = "Remaining Time";
|
||||
var countDownText = "Contest begins in";
|
||||
var startTime = moment("2018-06-16T21:00:00+09:00");
|
||||
var endTime = moment("2018-06-16T22:40:00+09:00");
|
||||
</script>
|
||||
<style></style>
|
||||
|
||||
|
||||
<link href="//img.atcoder.jp/public/6372bb3/css/cdn/select2.min.css" rel="stylesheet" />
|
||||
<link href="//img.atcoder.jp/public/6372bb3/css/cdn/select2-bootstrap.min.css" rel="stylesheet" />
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/lib/select2.min.js"></script>
|
||||
|
||||
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/ace/ace.js"></script>
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/ace/ext-language_tools.js"></script>
|
||||
|
||||
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/cdn/run_prettify.js"></script>
|
||||
|
||||
|
||||
<link rel="stylesheet" href="//img.atcoder.jp/public/6372bb3/css/cdn/katex.min.css">
|
||||
<script defer src="//img.atcoder.jp/public/6372bb3/js/cdn/katex.min.js"></script>
|
||||
<script defer src="//img.atcoder.jp/public/6372bb3/js/cdn/auto-render.min.js"></script>
|
||||
<script>$(function(){$('var').each(function(){var html=$(this).html().replace(/<sub>/g,'_{').replace(/<\/sub>/g,'}');$(this).html('\\('+html+'\\)');});});</script>
|
||||
<script>
|
||||
var katexOptions = {
|
||||
delimiters: [
|
||||
{left: "$$", right: "$$", display: true},
|
||||
|
||||
{left: "\\(", right: "\\)", display: false},
|
||||
{left: "\\[", right: "\\]", display: true}
|
||||
],
|
||||
ignoredTags: ["script", "noscript", "style", "textarea", "code", "option"],
|
||||
ignoredClasses: ["prettyprint", "source-code-for-copy"],
|
||||
throwOnError: false
|
||||
};
|
||||
document.addEventListener("DOMContentLoaded", function() { renderMathInElement(document.body, katexOptions);});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/base.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<script type="text/javascript">
|
||||
var __pParams = __pParams || [];
|
||||
__pParams.push({client_id: '468', c_1: 'atcodercontest', c_2: 'ClientSite'});
|
||||
</script>
|
||||
<script type="text/javascript" src="https://cdn.d2-apps.net/js/tr.js" async></script>
|
||||
|
||||
|
||||
<div id="modal-contest-start" class="modal fade" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">Contest started</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>AtCoder Beginner Contest 100 has begun.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal-contest-end" class="modal fade" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">Contest is over</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>AtCoder Beginner Contest 100 has ended.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="main-div" class="float-container">
|
||||
|
||||
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false">
|
||||
<span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="/home"></a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse" id="navbar-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
|
||||
<li><a class="contest-title" href="/contests/abc100">AtCoder Beginner Contest 100</a></li>
|
||||
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
|
||||
<li class="dropdown">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
|
||||
<img src='//img.atcoder.jp/assets/top/img/flag-lang/en.png'> English <span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/contests/abc100/tasks/abc100_c?lang=ja"><img src='//img.atcoder.jp/assets/top/img/flag-lang/ja.png'> 日本語</a></li>
|
||||
<li><a href="/contests/abc100/tasks/abc100_c?lang=en"><img src='//img.atcoder.jp/assets/top/img/flag-lang/en.png'> English</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
<li><a href="/register?continue=https%3A%2F%2Fatcoder.jp%2Fcontests%2Fabc100%2Ftasks%2Fabc100_c">Sign Up</a></li>
|
||||
<li><a href="/login?continue=https%3A%2F%2Fatcoder.jp%2Fcontests%2Fabc100%2Ftasks%2Fabc100_c">Sign In</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<form method="POST" name="form_logout" action="/logout?continue=https%3A%2F%2Fatcoder.jp%2Fcontests%2Fabc100%2Ftasks%2Fabc100_c">
|
||||
<input type="hidden" name="csrf_token" value="KwoiS7wTPLvccvgUDoQZ6H++fkjXMCchJrW6/YFqOJM=" />
|
||||
</form>
|
||||
<div id="main-container" class="container"
|
||||
style="padding-top:50px;">
|
||||
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div id="contest-nav-tabs" class="col-sm-12 mb-2 cnvtb-fixed">
|
||||
<div>
|
||||
<small class="contest-duration">
|
||||
|
||||
Contest Duration:
|
||||
<a href='http://www.timeanddate.com/worldclock/fixedtime.html?iso=20180616T2100&p1=248' target='blank'><time class='fixtime fixtime-full'>2018-06-16 21:00:00+0900</time></a> - <a href='http://www.timeanddate.com/worldclock/fixedtime.html?iso=20180616T2240&p1=248' target='blank'><time class='fixtime fixtime-full'>2018-06-16 22:40:00+0900</time></a> (local time)
|
||||
(100 minutes)
|
||||
|
||||
</small>
|
||||
<small class="back-to-home pull-right"><a href="/home">Back to Home</a></small>
|
||||
</div>
|
||||
<ul class="nav nav-tabs">
|
||||
<li><a href="/contests/abc100"><span class="glyphicon glyphicon-home" aria-hidden="true"></span> Top</a></li>
|
||||
|
||||
<li class="active"><a href="/contests/abc100/tasks"><span class="glyphicon glyphicon-tasks" aria-hidden="true"></span> Tasks</a></li>
|
||||
|
||||
|
||||
|
||||
<li><a href="/contests/abc100/clarifications"><span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span> Clarifications <span id="clar-badge" class="badge" ></span></a></li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li>
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-list" aria-hidden="true"></span> Results<span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/contests/abc100/submissions"><span class="glyphicon glyphicon-globe" aria-hidden="true"></span> All Submissions</a></li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li><a href="/contests/abc100/standings"><span class="glyphicon glyphicon-sort-by-attributes-alt" aria-hidden="true"></span> Standings</a></li>
|
||||
|
||||
|
||||
|
||||
<li><a href="/contests/abc100/standings/virtual"><span class="glyphicon glyphicon-sort-by-attributes-alt" aria-hidden="true"></span> Virtual Standings</a></li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li><a href="/contests/abc100/editorial"><span class="glyphicon glyphicon-book" aria-hidden="true"></span> Editorial</a></li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="pull-right"><a id="fix-cnvtb" href="javascript:void(0)"><span class="glyphicon glyphicon-pushpin" aria-hidden="true"></span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<span class="h2">
|
||||
C - *3 or /2
|
||||
<a class="btn btn-default btn-sm" href="/contests/abc100/tasks/abc100_c/editorial">Editorial</a>
|
||||
</span>
|
||||
<span id="task-lang-btn" class="pull-right"><span data-lang="ja"><img src='//img.atcoder.jp/assets/top/img/flag-lang/ja.png'></span> / <span data-lang="en"><img src='//img.atcoder.jp/assets/top/img/flag-lang/en.png'></span></span>
|
||||
<script>
|
||||
$(function() {
|
||||
var ts = $('#task-statement span.lang');
|
||||
if (ts.children('span').size() <= 1) {
|
||||
$('#task-lang-btn').hide();
|
||||
ts.children('span').show();
|
||||
return;
|
||||
}
|
||||
|
||||
var REMEMBER_LB = 5;
|
||||
var LS_KEY = 'task_lang';
|
||||
var taskLang = getLS(LS_KEY) || '';
|
||||
function isTaskLangSet(taskLang) { return taskLang === 'ja' || taskLang === 'en';}
|
||||
if (isTaskLangSet(taskLang)) {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
if (params.get('lang')) {
|
||||
setLS(LS_KEY, REMEMBER_LB);
|
||||
taskLang = LANG;
|
||||
}
|
||||
} else {
|
||||
taskLang = LANG;
|
||||
}
|
||||
ts.children('span.lang-' + taskLang).show();
|
||||
|
||||
$('#task-lang-btn span').click(function() {
|
||||
var l = $(this).data('lang');
|
||||
ts.children('span').hide();
|
||||
ts.children('span.lang-' + l).show();
|
||||
|
||||
taskLang = getLS(LS_KEY) || '';
|
||||
let changeTimes = 0;
|
||||
if (isTaskLangSet(taskLang)) {
|
||||
changeTimes = REMEMBER_LB;
|
||||
} else {
|
||||
changeTimes = parseInt(taskLang, 10);
|
||||
if (isNaN(changeTimes)) changeTimes = 0;
|
||||
changeTimes++;
|
||||
}
|
||||
if (changeTimes < REMEMBER_LB) setLS(LS_KEY, changeTimes);
|
||||
else setLS(LS_KEY, l);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<hr/>
|
||||
<p>
|
||||
Time Limit: 2 sec / Memory Limit: 976 MiB
|
||||
|
||||
|
||||
</p>
|
||||
|
||||
<div id="task-statement">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<span class="lang">
|
||||
<span class="lang-ja">
|
||||
<p>配点: <var>300</var> 点</p>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>問題文</h3>
|
||||
<p>AtCoder Beginner Contest 100 の開催にともなって, AtCoder 社では長さ <var>N</var> の数列 <var>a = </var>{<var>a_1, a_2, a_3, ..., a_N</var>} が飾られることになった. <br />
|
||||
社員のすぬけ君は, この数列で遊んでみようと思った. </p>
|
||||
<p>具体的には, 以下の操作をできるだけ多くの回数繰り返そうと思った. </p>
|
||||
<pre><var>1 \leq i \leq N</var> を満たす全ての <var>i</var> に対して, それぞれ「<var>a_i</var> の値を <var>2</var> で割る」「<var>a_i</var> の値を <var>3</var> 倍する」のどちらかを行う.
|
||||
ただし, 全ての <var>i</var> に対して <var>3</var> 倍することはできず, 操作後の <var>a_i</var> の値は整数でなければならない.
|
||||
</pre>
|
||||
|
||||
<p>最大で何回の操作が可能か, 求めなさい. </p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>制約</h3>
|
||||
<ul>
|
||||
<li><var>N</var> は <var>1</var> 以上 <var>10 \ 000</var> 以下の整数</li>
|
||||
<li><var>a_i</var> は <var>1</var> 以上 <var>1 \ 000 \ 000 \ 000</var> 以下の整数</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="io-style">
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>入力</h3>
|
||||
<p>入力は以下の形式で標準入力から与えられる. </p>
|
||||
<pre><var>N</var>
|
||||
<var>a_1</var> <var>a_2</var> <var>a_3</var> <var>...</var> <var>a_N</var>
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>出力</h3>
|
||||
<p>すぬけ君が行える最大の操作回数を出力しなさい. </p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>入力例 1</h3><pre>3
|
||||
5 2 4
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>出力例 1</h3><pre>3
|
||||
</pre>
|
||||
|
||||
<p>最初, 数列は <var>{5, 2, 4}</var> であるが, 以下のように操作すれば <var>3</var> 回の操作を行うことができる. </p>
|
||||
<ul>
|
||||
<li>最初に, <var>a_1</var> を <var>3</var> 倍し, <var>a_2</var> を <var>3</var> 倍し, <var>a_3</var> を <var>2</var> で割る. すると数列は <var>{15, 6, 2}</var> となる.</li>
|
||||
<li>次に, <var>a_1</var> を <var>3</var> 倍し, <var>a_2</var> を <var>2</var> で割り, <var>a_3</var> を <var>3</var> 倍する. すると数列は <var>{45, 3, 6}</var> となる.</li>
|
||||
<li>最後に, <var>a_1</var> を <var>3</var> 倍し, <var>a_2</var> を <var>3</var> 倍し, <var>a_3</var> を <var>2</var> で割る. すると数列は <var>{135, 9, 3}</var> となる.</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>入力例 2</h3><pre>4
|
||||
631 577 243 199
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>出力例 2</h3><pre>0
|
||||
</pre>
|
||||
|
||||
<p>全ての要素が奇数なので, 操作はできない. よって答えは <var>0</var> である. </p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>入力例 3</h3><pre>10
|
||||
2184 2126 1721 1800 1024 2528 3360 1945 1280 1776
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>出力例 3</h3><pre>39
|
||||
</pre></section>
|
||||
</div>
|
||||
</span>
|
||||
<span class="lang-en">
|
||||
<p>Score: <var>300</var> points</p>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Problem Statement</h3>
|
||||
<p>As AtCoder Beginner Contest 100 is taking place, the office of AtCoder, Inc. is decorated with a sequence of length <var>N</var>, <var>a = </var>{<var>a_1, a_2, a_3, ..., a_N</var>}.<br />
|
||||
Snuke, an employee, would like to play with this sequence.</p>
|
||||
<p>Specifically, he would like to repeat the following operation as many times as possible:</p>
|
||||
<pre>For every <var>i</var> satisfying <var>1 \leq i \leq N</var>, perform one of the following: "divide <var>a_i</var> by <var>2</var>" and "multiply <var>a_i</var> by <var>3</var>".
|
||||
Here, choosing "multiply <var>a_i</var> by <var>3</var>" for every <var>i</var> is not allowed, and the value of <var>a_i</var> after the operation must be an integer.
|
||||
</pre>
|
||||
|
||||
<p>At most how many operations can be performed?</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Constraints</h3>
|
||||
<ul>
|
||||
<li><var>N</var> is an integer between <var>1</var> and <var>10 \ 000</var> (inclusive).</li>
|
||||
<li><var>a_i</var> is an integer between <var>1</var> and <var>1 \ 000 \ 000 \ 000</var> (inclusive).</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="io-style">
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Input</h3>
|
||||
<p>Input is given from Standard Input in the following format:</p>
|
||||
<pre><var>N</var>
|
||||
<var>a_1</var> <var>a_2</var> <var>a_3</var> <var>...</var> <var>a_N</var>
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Output</h3>
|
||||
<p>Print the maximum number of operations that Snuke can perform.</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Sample Input 1</h3><pre>3
|
||||
5 2 4
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Sample Output 1</h3><pre>3
|
||||
</pre>
|
||||
|
||||
<p>The sequence is initially <var>{5, 2, 4}</var>. Three operations can be performed as follows:</p>
|
||||
<ul>
|
||||
<li>First, multiply <var>a_1</var> by <var>3</var>, multiply <var>a_2</var> by <var>3</var> and divide <var>a_3</var> by <var>2</var>. The sequence is now <var>{15, 6, 2}</var>.</li>
|
||||
<li>Next, multiply <var>a_1</var> by <var>3</var>, divide <var>a_2</var> by <var>2</var> and multiply <var>a_3</var> by <var>3</var>. The sequence is now <var>{45, 3, 6}</var>.</li>
|
||||
<li>Finally, multiply <var>a_1</var> by <var>3</var>, multiply <var>a_2</var> by <var>3</var> and divide <var>a_3</var> by <var>2</var>. The sequence is now <var>{135, 9, 3}</var>.</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Sample Input 2</h3><pre>4
|
||||
631 577 243 199
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Sample Output 2</h3><pre>0
|
||||
</pre>
|
||||
|
||||
<p>No operation can be performed since all the elements are odd. Thus, the answer is <var>0</var>.</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Sample Input 3</h3><pre>10
|
||||
2184 2126 1721 1800 1024 2528 3360 1945 1280 1776
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Sample Output 3</h3><pre>39
|
||||
</pre></section>
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
|
||||
<div class="a2a_kit a2a_kit_size_20 a2a_default_style pull-right" data-a2a-url="https://atcoder.jp/contests/abc100/tasks/abc100_c?lang=en" data-a2a-title="C - *3 or /2">
|
||||
<a class="a2a_button_facebook"></a>
|
||||
<a class="a2a_button_twitter"></a>
|
||||
|
||||
<a class="a2a_button_telegram"></a>
|
||||
|
||||
<a class="a2a_dd" href="https://www.addtoany.com/share"></a>
|
||||
</div>
|
||||
|
||||
|
||||
<script async src="//static.addtoany.com/menu/page.js"></script>
|
||||
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
<div class="container" style="margin-bottom: 80px;">
|
||||
<footer class="footer">
|
||||
|
||||
<ul>
|
||||
<li><a href="/contests/abc100/rules">Rule</a></li>
|
||||
<li><a href="/contests/abc100/glossary">Glossary</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li><a href="/tos">Terms of service</a></li>
|
||||
<li><a href="/privacy">Privacy Policy</a></li>
|
||||
<li><a href="/personal">Information Protection Policy</a></li>
|
||||
<li><a href="/company">Company</a></li>
|
||||
<li><a href="/faq">FAQ</a></li>
|
||||
<li><a href="/contact">Contact</a></li>
|
||||
|
||||
</ul>
|
||||
<div class="text-center">
|
||||
<small id="copyright">Copyright Since 2012 ©<a href="http://atcoder.co.jp">AtCoder Inc.</a> All rights reserved.</small>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<p id="fixed-server-timer" class="contest-timer"></p>
|
||||
<div id="scroll-page-top" style="display:none;"><span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span> Page Top</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
728
tests/fixtures/atcoder_task_abc100_d.html
vendored
Normal file
728
tests/fixtures/atcoder_task_abc100_d.html
vendored
Normal file
|
|
@ -0,0 +1,728 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>D - Patisserie ABC</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta http-equiv="Content-Language" content="en">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="google-site-verification" content="nXGC_JxO0yoP1qBzMnYD_xgufO6leSLw1kyNo2HZltM" />
|
||||
|
||||
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-RC512FD18N"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('set', 'user_properties', {
|
||||
|
||||
'login_status': 'logged_out',
|
||||
|
||||
});
|
||||
gtag('config', 'G-RC512FD18N');
|
||||
</script>
|
||||
|
||||
|
||||
<meta name="description" content="AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.">
|
||||
<meta name="author" content="AtCoder Inc.">
|
||||
|
||||
<meta property="og:site_name" content="AtCoder">
|
||||
|
||||
<meta property="og:title" content="D - Patisserie ABC" />
|
||||
<meta property="og:description" content="AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online." />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://atcoder.jp/contests/abc100/tasks/abc100_d" />
|
||||
<meta property="og:image" content="https://img.atcoder.jp/assets/atcoder.png" />
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@atcoder" />
|
||||
|
||||
<meta property="twitter:title" content="D - Patisserie ABC" />
|
||||
|
||||
<link href="//fonts.googleapis.com/css?family=Lato:400,700" rel="stylesheet" type="text/css">
|
||||
<link rel="stylesheet" type="text/css" href="//img.atcoder.jp/public/6372bb3/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="//img.atcoder.jp/public/6372bb3/css/base.css">
|
||||
<link rel="shortcut icon" type="image/png" href="//img.atcoder.jp/assets/favicon.png">
|
||||
<link rel="apple-touch-icon" href="//img.atcoder.jp/assets/atcoder.png">
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/lib/jquery-1.9.1.min.js"></script>
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/lib/bootstrap.min.js"></script>
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/cdn/js.cookie.min.js"></script>
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/cdn/moment.min.js"></script>
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/cdn/moment_js-ja.js"></script>
|
||||
<script>
|
||||
var LANG = "en";
|
||||
var userScreenName = "";
|
||||
var csrfToken = "GAGswbeHt5p1jIJSPp2R1sTxFC3jW6sLK2K7L2aRmUI="
|
||||
</script>
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/utils.js"></script>
|
||||
|
||||
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/contest.js"></script>
|
||||
<link href="//img.atcoder.jp/public/6372bb3/css/contest.css" rel="stylesheet" />
|
||||
<script>
|
||||
var contestScreenName = "abc100";
|
||||
var remainingText = "Remaining Time";
|
||||
var countDownText = "Contest begins in";
|
||||
var startTime = moment("2018-06-16T21:00:00+09:00");
|
||||
var endTime = moment("2018-06-16T22:40:00+09:00");
|
||||
</script>
|
||||
<style></style>
|
||||
|
||||
|
||||
<link href="//img.atcoder.jp/public/6372bb3/css/cdn/select2.min.css" rel="stylesheet" />
|
||||
<link href="//img.atcoder.jp/public/6372bb3/css/cdn/select2-bootstrap.min.css" rel="stylesheet" />
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/lib/select2.min.js"></script>
|
||||
|
||||
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/ace/ace.js"></script>
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/ace/ext-language_tools.js"></script>
|
||||
|
||||
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/cdn/run_prettify.js"></script>
|
||||
|
||||
|
||||
<link rel="stylesheet" href="//img.atcoder.jp/public/6372bb3/css/cdn/katex.min.css">
|
||||
<script defer src="//img.atcoder.jp/public/6372bb3/js/cdn/katex.min.js"></script>
|
||||
<script defer src="//img.atcoder.jp/public/6372bb3/js/cdn/auto-render.min.js"></script>
|
||||
<script>$(function(){$('var').each(function(){var html=$(this).html().replace(/<sub>/g,'_{').replace(/<\/sub>/g,'}');$(this).html('\\('+html+'\\)');});});</script>
|
||||
<script>
|
||||
var katexOptions = {
|
||||
delimiters: [
|
||||
{left: "$$", right: "$$", display: true},
|
||||
|
||||
{left: "\\(", right: "\\)", display: false},
|
||||
{left: "\\[", right: "\\]", display: true}
|
||||
],
|
||||
ignoredTags: ["script", "noscript", "style", "textarea", "code", "option"],
|
||||
ignoredClasses: ["prettyprint", "source-code-for-copy"],
|
||||
throwOnError: false
|
||||
};
|
||||
document.addEventListener("DOMContentLoaded", function() { renderMathInElement(document.body, katexOptions);});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="//img.atcoder.jp/public/6372bb3/js/base.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<script type="text/javascript">
|
||||
var __pParams = __pParams || [];
|
||||
__pParams.push({client_id: '468', c_1: 'atcodercontest', c_2: 'ClientSite'});
|
||||
</script>
|
||||
<script type="text/javascript" src="https://cdn.d2-apps.net/js/tr.js" async></script>
|
||||
|
||||
|
||||
<div id="modal-contest-start" class="modal fade" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">Contest started</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>AtCoder Beginner Contest 100 has begun.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="modal-contest-end" class="modal fade" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title">Contest is over</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>AtCoder Beginner Contest 100 has ended.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="main-div" class="float-container">
|
||||
|
||||
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false">
|
||||
<span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="/home"></a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse" id="navbar-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
|
||||
<li><a class="contest-title" href="/contests/abc100">AtCoder Beginner Contest 100</a></li>
|
||||
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
|
||||
<li class="dropdown">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
|
||||
<img src='//img.atcoder.jp/assets/top/img/flag-lang/en.png'> English <span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/contests/abc100/tasks/abc100_d?lang=ja"><img src='//img.atcoder.jp/assets/top/img/flag-lang/ja.png'> 日本語</a></li>
|
||||
<li><a href="/contests/abc100/tasks/abc100_d?lang=en"><img src='//img.atcoder.jp/assets/top/img/flag-lang/en.png'> English</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
<li><a href="/register?continue=https%3A%2F%2Fatcoder.jp%2Fcontests%2Fabc100%2Ftasks%2Fabc100_d">Sign Up</a></li>
|
||||
<li><a href="/login?continue=https%3A%2F%2Fatcoder.jp%2Fcontests%2Fabc100%2Ftasks%2Fabc100_d">Sign In</a></li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<form method="POST" name="form_logout" action="/logout?continue=https%3A%2F%2Fatcoder.jp%2Fcontests%2Fabc100%2Ftasks%2Fabc100_d">
|
||||
<input type="hidden" name="csrf_token" value="GAGswbeHt5p1jIJSPp2R1sTxFC3jW6sLK2K7L2aRmUI=" />
|
||||
</form>
|
||||
<div id="main-container" class="container"
|
||||
style="padding-top:50px;">
|
||||
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div id="contest-nav-tabs" class="col-sm-12 mb-2 cnvtb-fixed">
|
||||
<div>
|
||||
<small class="contest-duration">
|
||||
|
||||
Contest Duration:
|
||||
<a href='http://www.timeanddate.com/worldclock/fixedtime.html?iso=20180616T2100&p1=248' target='blank'><time class='fixtime fixtime-full'>2018-06-16 21:00:00+0900</time></a> - <a href='http://www.timeanddate.com/worldclock/fixedtime.html?iso=20180616T2240&p1=248' target='blank'><time class='fixtime fixtime-full'>2018-06-16 22:40:00+0900</time></a> (local time)
|
||||
(100 minutes)
|
||||
|
||||
</small>
|
||||
<small class="back-to-home pull-right"><a href="/home">Back to Home</a></small>
|
||||
</div>
|
||||
<ul class="nav nav-tabs">
|
||||
<li><a href="/contests/abc100"><span class="glyphicon glyphicon-home" aria-hidden="true"></span> Top</a></li>
|
||||
|
||||
<li class="active"><a href="/contests/abc100/tasks"><span class="glyphicon glyphicon-tasks" aria-hidden="true"></span> Tasks</a></li>
|
||||
|
||||
|
||||
|
||||
<li><a href="/contests/abc100/clarifications"><span class="glyphicon glyphicon-question-sign" aria-hidden="true"></span> Clarifications <span id="clar-badge" class="badge" ></span></a></li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li>
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false"><span class="glyphicon glyphicon-list" aria-hidden="true"></span> Results<span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/contests/abc100/submissions"><span class="glyphicon glyphicon-globe" aria-hidden="true"></span> All Submissions</a></li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li><a href="/contests/abc100/standings"><span class="glyphicon glyphicon-sort-by-attributes-alt" aria-hidden="true"></span> Standings</a></li>
|
||||
|
||||
|
||||
|
||||
<li><a href="/contests/abc100/standings/virtual"><span class="glyphicon glyphicon-sort-by-attributes-alt" aria-hidden="true"></span> Virtual Standings</a></li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li><a href="/contests/abc100/editorial"><span class="glyphicon glyphicon-book" aria-hidden="true"></span> Editorial</a></li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li class="pull-right"><a id="fix-cnvtb" href="javascript:void(0)"><span class="glyphicon glyphicon-pushpin" aria-hidden="true"></span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-sm-12">
|
||||
<span class="h2">
|
||||
D - Patisserie ABC
|
||||
<a class="btn btn-default btn-sm" href="/contests/abc100/tasks/abc100_d/editorial">Editorial</a>
|
||||
</span>
|
||||
<span id="task-lang-btn" class="pull-right"><span data-lang="ja"><img src='//img.atcoder.jp/assets/top/img/flag-lang/ja.png'></span> / <span data-lang="en"><img src='//img.atcoder.jp/assets/top/img/flag-lang/en.png'></span></span>
|
||||
<script>
|
||||
$(function() {
|
||||
var ts = $('#task-statement span.lang');
|
||||
if (ts.children('span').size() <= 1) {
|
||||
$('#task-lang-btn').hide();
|
||||
ts.children('span').show();
|
||||
return;
|
||||
}
|
||||
|
||||
var REMEMBER_LB = 5;
|
||||
var LS_KEY = 'task_lang';
|
||||
var taskLang = getLS(LS_KEY) || '';
|
||||
function isTaskLangSet(taskLang) { return taskLang === 'ja' || taskLang === 'en';}
|
||||
if (isTaskLangSet(taskLang)) {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
if (params.get('lang')) {
|
||||
setLS(LS_KEY, REMEMBER_LB);
|
||||
taskLang = LANG;
|
||||
}
|
||||
} else {
|
||||
taskLang = LANG;
|
||||
}
|
||||
ts.children('span.lang-' + taskLang).show();
|
||||
|
||||
$('#task-lang-btn span').click(function() {
|
||||
var l = $(this).data('lang');
|
||||
ts.children('span').hide();
|
||||
ts.children('span.lang-' + l).show();
|
||||
|
||||
taskLang = getLS(LS_KEY) || '';
|
||||
let changeTimes = 0;
|
||||
if (isTaskLangSet(taskLang)) {
|
||||
changeTimes = REMEMBER_LB;
|
||||
} else {
|
||||
changeTimes = parseInt(taskLang, 10);
|
||||
if (isNaN(changeTimes)) changeTimes = 0;
|
||||
changeTimes++;
|
||||
}
|
||||
if (changeTimes < REMEMBER_LB) setLS(LS_KEY, changeTimes);
|
||||
else setLS(LS_KEY, l);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<hr/>
|
||||
<p>
|
||||
Time Limit: 2 sec / Memory Limit: 976 MiB
|
||||
|
||||
|
||||
</p>
|
||||
|
||||
<div id="task-statement">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<span class="lang">
|
||||
<span class="lang-ja">
|
||||
<p>配点: <var>400</var> 点</p>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>問題文</h3>
|
||||
<p>高橋君はプロのパティシエになり, AtCoder Beginner Contest 100 を記念して, 「ABC洋菓子店」というお店を開いた. </p>
|
||||
<p>ABC洋菓子店では, <var>N</var> 種類のケーキを売っている.<br />
|
||||
各種類のケーキには「綺麗さ」「おいしさ」「人気度」の <var>3</var> つの値を持ち, <var>i</var> 種類目のケーキの綺麗さは <var>x_i</var>, おいしさは <var>y_i</var>, 人気度は <var>z_i</var> である.<br />
|
||||
これらの値は <var>0</var> 以下である可能性もある. </p>
|
||||
<p>りんごさんは, ABC洋菓子店で <var>M</var> 個のケーキを食べることにした. 彼は次のように, 食べるケーキの組み合わせを選ぶことにした. </p>
|
||||
<ul>
|
||||
<li>同じ種類のケーキを <var>2</var> 個以上食べない.</li>
|
||||
<li>上の条件を満たしつつ, (綺麗さの合計の絶対値) + (おいしさの合計の絶対値) + (人気度の合計の絶対値) が最大になるように選ぶ.</li>
|
||||
</ul>
|
||||
<p>このとき, りんごさんが選ぶケーキの (綺麗さの合計の絶対値) + (おいしさの合計の絶対値) + (人気度の合計の絶対値) の最大値を求めなさい. </p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>制約</h3>
|
||||
<ul>
|
||||
<li><var>N</var> は <var>1</var> 以上 <var>1 \ 000</var> 以下の整数</li>
|
||||
<li><var>M</var> は <var>0</var> 以上 <var>N</var> 以下の整数</li>
|
||||
<li><var>x_i, y_i, z_i \ (1 \leq i \leq N)</var> は, それぞれ <var>-10 \ 000 \ 000 \ 000</var> 以上 <var>10 \ 000 \ 000 \ 000</var> 以下の整数.</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="io-style">
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>入力</h3>
|
||||
<p>入力は以下の形式で標準入力から与えられる. </p>
|
||||
<pre><var>N</var> <var>M</var>
|
||||
<var>x_1</var> <var>y_1</var> <var>z_1</var>
|
||||
<var>x_2</var> <var>y_2</var> <var>z_2</var>
|
||||
<var>:</var> <var>:</var>
|
||||
<var>x_N</var> <var>y_N</var> <var>z_N</var>
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>出力</h3>
|
||||
<p>りんごさんが選ぶケーキの (綺麗さの合計の絶対値) + (おいしさの合計の絶対値) + (人気度の合計の絶対値) の最大値を出力しなさい. </p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>入力例 1</h3><pre>5 3
|
||||
3 1 4
|
||||
1 5 9
|
||||
2 6 5
|
||||
3 5 8
|
||||
9 7 9
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>出力例 1</h3><pre>56
|
||||
</pre>
|
||||
|
||||
<p><var>2, 4, 5</var> 種類目のケーキを食べることを考える. そのとき, 「綺麗さ」「おいしさ」「人気度」の合計はそれぞれ次のようになる. </p>
|
||||
<ul>
|
||||
<li>綺麗さ:<var>1 + 3 + 9 = 13</var></li>
|
||||
<li>おいしさ:<var>5 + 5 + 7 = 17</var></li>
|
||||
<li>人気度:<var>9 + 8 + 9 = 26</var></li>
|
||||
</ul>
|
||||
<p>このときの (綺麗さの合計の絶対値) + (おいしさの合計の絶対値) + (人気度の合計の絶対値) は <var>13 + 17 + 26 = 56</var> となり, これが最大になる. </p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>入力例 2</h3><pre>5 3
|
||||
1 -2 3
|
||||
-4 5 -6
|
||||
7 -8 -9
|
||||
-10 11 -12
|
||||
13 -14 15
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>出力例 2</h3><pre>54
|
||||
</pre>
|
||||
|
||||
<p><var>1, 3, 5</var> 種類目のケーキを食べることを考える. そのとき, 「綺麗さ」「おいしさ」「人気度」の合計はそれぞれ次のようになる. </p>
|
||||
<ul>
|
||||
<li>綺麗さ:<var>1 + 7 + 13 = 21</var></li>
|
||||
<li>おいしさ:<var>(-2) + (-8) + (-14) = -24</var></li>
|
||||
<li>人気度:<var>3 + (-9) + 15 = 9</var></li>
|
||||
</ul>
|
||||
<p>このときの (綺麗さの合計の絶対値) + (おいしさの合計の絶対値) + (人気度の合計の絶対値) は <var>21 + 24 + 9 = 54</var> となり, これが最大になる. </p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>入力例 3</h3><pre>10 5
|
||||
10 -80 21
|
||||
23 8 38
|
||||
-94 28 11
|
||||
-26 -2 18
|
||||
-69 72 79
|
||||
-26 -86 -54
|
||||
-72 -50 59
|
||||
21 65 -32
|
||||
40 -94 87
|
||||
-62 18 82
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>出力例 3</h3><pre>638
|
||||
</pre>
|
||||
|
||||
<p><var>3, 4, 5, 7, 10</var> 種類目のケーキを食べると, 綺麗さの合計は <var>-323</var>, おいしさの合計は <var>66</var>, 人気度の合計は <var>249</var> となる.<br />
|
||||
このときの (綺麗さの合計の絶対値) + (おいしさの合計の絶対値) + (人気度の合計の絶対値) は <var>323 + 66 + 249 = 638</var> となり, これが最大になる. </p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>入力例 4</h3><pre>3 2
|
||||
2000000000 -9000000000 4000000000
|
||||
7000000000 -5000000000 3000000000
|
||||
6000000000 -1000000000 8000000000
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>出力例 4</h3><pre>30000000000
|
||||
</pre>
|
||||
|
||||
<p>ケーキの綺麗さ, おいしさ, 人気度や出力すべき値が, 32bit 整数に収まらない場合もある. </p></section>
|
||||
</div>
|
||||
</span>
|
||||
<span class="lang-en">
|
||||
<p>Score: <var>400</var> points</p>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Problem Statement</h3>
|
||||
<p>Takahashi became a pastry chef and opened a shop <em>La Confiserie d'ABC</em> to celebrate AtCoder Beginner Contest 100.</p>
|
||||
<p>The shop sells <var>N</var> kinds of cakes.<br />
|
||||
Each kind of cake has three parameters "beauty", "tastiness" and "popularity". The <var>i</var>-th kind of cake has the beauty of <var>x_i</var>, the tastiness of <var>y_i</var> and the popularity of <var>z_i</var>.<br />
|
||||
These values may be zero or negative.</p>
|
||||
<p>Ringo has decided to have <var>M</var> pieces of cakes here. He will choose the set of cakes as follows:</p>
|
||||
<ul>
|
||||
<li>Do not have two or more pieces of the same kind of cake.</li>
|
||||
<li>Under the condition above, choose the set of cakes to maximize (the absolute value of the total beauty) + (the absolute value of the total tastiness) + (the absolute value of the total popularity).</li>
|
||||
</ul>
|
||||
<p>Find the maximum possible value of (the absolute value of the total beauty) + (the absolute value of the total tastiness) + (the absolute value of the total popularity) for the set of cakes that Ringo chooses.</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Constraints</h3>
|
||||
<ul>
|
||||
<li><var>N</var> is an integer between <var>1</var> and <var>1 \ 000</var> (inclusive).</li>
|
||||
<li><var>M</var> is an integer between <var>0</var> and <var>N</var> (inclusive).</li>
|
||||
<li><var>x_i, y_i, z_i \ (1 \leq i \leq N)</var> are integers between <var>-10 \ 000 \ 000 \ 000</var> and <var>10 \ 000 \ 000 \ 000</var> (inclusive).</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="io-style">
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Input</h3>
|
||||
<p>Input is given from Standard Input in the following format:</p>
|
||||
<pre><var>N</var> <var>M</var>
|
||||
<var>x_1</var> <var>y_1</var> <var>z_1</var>
|
||||
<var>x_2</var> <var>y_2</var> <var>z_2</var>
|
||||
<var>:</var> <var>:</var>
|
||||
<var>x_N</var> <var>y_N</var> <var>z_N</var>
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Output</h3>
|
||||
<p>Print the maximum possible value of (the absolute value of the total beauty) + (the absolute value of the total tastiness) + (the absolute value of the total popularity) for the set of cakes that Ringo chooses.</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Sample Input 1</h3><pre>5 3
|
||||
3 1 4
|
||||
1 5 9
|
||||
2 6 5
|
||||
3 5 8
|
||||
9 7 9
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Sample Output 1</h3><pre>56
|
||||
</pre>
|
||||
|
||||
<p>Consider having the <var>2</var>-nd, <var>4</var>-th and <var>5</var>-th kinds of cakes. The total beauty, tastiness and popularity will be as follows:</p>
|
||||
<ul>
|
||||
<li>Beauty: <var>1 + 3 + 9 = 13</var></li>
|
||||
<li>Tastiness: <var>5 + 5 + 7 = 17</var></li>
|
||||
<li>Popularity: <var>9 + 8 + 9 = 26</var></li>
|
||||
</ul>
|
||||
<p>The value (the absolute value of the total beauty) + (the absolute value of the total tastiness) + (the absolute value of the total popularity) here is <var>13 + 17 + 26 = 56</var>. This is the maximum value.</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Sample Input 2</h3><pre>5 3
|
||||
1 -2 3
|
||||
-4 5 -6
|
||||
7 -8 -9
|
||||
-10 11 -12
|
||||
13 -14 15
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Sample Output 2</h3><pre>54
|
||||
</pre>
|
||||
|
||||
<p>Consider having the <var>1</var>-st, <var>3</var>-rd and <var>5</var>-th kinds of cakes. The total beauty, tastiness and popularity will be as follows:</p>
|
||||
<ul>
|
||||
<li>Beauty: <var>1 + 7 + 13 = 21</var></li>
|
||||
<li>Tastiness: <var>(-2) + (-8) + (-14) = -24</var></li>
|
||||
<li>Popularity: <var>3 + (-9) + 15 = 9</var></li>
|
||||
</ul>
|
||||
<p>The value (the absolute value of the total beauty) + (the absolute value of the total tastiness) + (the absolute value of the total popularity) here is <var>21 + 24 + 9 = 54</var>. This is the maximum value.</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Sample Input 3</h3><pre>10 5
|
||||
10 -80 21
|
||||
23 8 38
|
||||
-94 28 11
|
||||
-26 -2 18
|
||||
-69 72 79
|
||||
-26 -86 -54
|
||||
-72 -50 59
|
||||
21 65 -32
|
||||
40 -94 87
|
||||
-62 18 82
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Sample Output 3</h3><pre>638
|
||||
</pre>
|
||||
|
||||
<p>If we have the <var>3</var>-rd, <var>4</var>-th, <var>5</var>-th, <var>7</var>-th and <var>10</var>-th kinds of cakes, the total beauty, tastiness and popularity will be <var>-323</var>, <var>66</var> and <var>249</var>, respectively.<br />
|
||||
The value (the absolute value of the total beauty) + (the absolute value of the total tastiness) + (the absolute value of the total popularity) here is <var>323 + 66 + 249 = 638</var>. This is the maximum value.</p>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Sample Input 4</h3><pre>3 2
|
||||
2000000000 -9000000000 4000000000
|
||||
7000000000 -5000000000 3000000000
|
||||
6000000000 -1000000000 8000000000
|
||||
</pre>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="part">
|
||||
<section>
|
||||
<h3>Sample Output 4</h3><pre>30000000000
|
||||
</pre>
|
||||
|
||||
<p>The values of the beauty, tastiness and popularity of the cakes and the value to be printed may not fit into 32-bit integers.</p></section>
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
|
||||
<div class="a2a_kit a2a_kit_size_20 a2a_default_style pull-right" data-a2a-url="https://atcoder.jp/contests/abc100/tasks/abc100_d?lang=en" data-a2a-title="D - Patisserie ABC">
|
||||
<a class="a2a_button_facebook"></a>
|
||||
<a class="a2a_button_twitter"></a>
|
||||
|
||||
<a class="a2a_button_telegram"></a>
|
||||
|
||||
<a class="a2a_dd" href="https://www.addtoany.com/share"></a>
|
||||
</div>
|
||||
|
||||
|
||||
<script async src="//static.addtoany.com/menu/page.js"></script>
|
||||
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
<div class="container" style="margin-bottom: 80px;">
|
||||
<footer class="footer">
|
||||
|
||||
<ul>
|
||||
<li><a href="/contests/abc100/rules">Rule</a></li>
|
||||
<li><a href="/contests/abc100/glossary">Glossary</a></li>
|
||||
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li><a href="/tos">Terms of service</a></li>
|
||||
<li><a href="/privacy">Privacy Policy</a></li>
|
||||
<li><a href="/personal">Information Protection Policy</a></li>
|
||||
<li><a href="/company">Company</a></li>
|
||||
<li><a href="/faq">FAQ</a></li>
|
||||
<li><a href="/contact">Contact</a></li>
|
||||
|
||||
</ul>
|
||||
<div class="text-center">
|
||||
<small id="copyright">Copyright Since 2012 ©<a href="http://atcoder.co.jp">AtCoder Inc.</a> All rights reserved.</small>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<p id="fixed-server-timer" class="contest-timer"></p>
|
||||
<div id="scroll-page-top" style="display:none;"><span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span> Page Top</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
1095
tests/fixtures/codeforces_1550_problems.html
vendored
Normal file
1095
tests/fixtures/codeforces_1550_problems.html
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue