惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
DataBreaches.Net
S
Schneier on Security
T
The Exploit Database - CXSecurity.com
Webroot Blog
Webroot Blog
AI
AI
P
Palo Alto Networks Blog
Attack and Defense Labs
Attack and Defense Labs
WordPress大学
WordPress大学
月光博客
月光博客
阮一峰的网络日志
阮一峰的网络日志
Spread Privacy
Spread Privacy
T
Tor Project blog
罗磊的独立博客
小众软件
小众软件
S
Security Affairs
酷 壳 – CoolShell
酷 壳 – CoolShell
量子位
Apple Machine Learning Research
Apple Machine Learning Research
T
Threatpost
NISL@THU
NISL@THU
博客园_首页
PCI Perspectives
PCI Perspectives
大猫的无限游戏
大猫的无限游戏
IT之家
IT之家
N
News and Events Feed by Topic
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Forbes - Security
Forbes - Security
博客园 - 叶小钗
D
Darknet – Hacking Tools, Hacker News & Cyber Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
L
LINUX DO - 热门话题
T
Threat Research - Cisco Blogs
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
腾讯CDC
Security Latest
Security Latest
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
The Cloudflare Blog
A
About on SuperTechFans
爱范儿
爱范儿
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
TaoSecurity Blog
TaoSecurity Blog
宝玉的分享
宝玉的分享
G
GRAHAM CLULEY
雷峰网
雷峰网
F
Full Disclosure
I
Intezer
Cloudbric
Cloudbric
博客园 - 三生石上(FineUI控件)
U
Unit 42

hayato

Chromium's DOM Deep Dive: Understanding Shadow DOM and Tree Structures - hayato Introducing the Task Scheduler in Chromium's Network Stack: A 0.3% Improvement in Loading Speed - hayato 出版のお知らせ 「普通の人が資産運用で99点をとる方法とその考え方」 - hayato Resource loading with Content Addressable Bundles - hayato 普通の人が資産運用で99点をとる方法とその考え方 - hayato Imperative Shadow DOM Distribution API - hayato Google にソフトウェアエンジニアとして入社して 10 年と 10 日がたちました - hayato Web のつくりかた: ソフトウェアエンジニアリングと雰囲気で理解する Web 標準とブラウザのつくりかた - hayato ブラウザのしくみ: データ構造とアルゴリズムと雰囲気で理解する DOM と Shadow DOM - hayato Rust が最強のプログラミング言語である証明 - hayato 六本木ではたらくソフトウェアエンジニアへのよくある質問とその答え (FAQ) (2015 - 2017) - hayato What's New in Shadow DOM v1 (by examples) - hayato Simple timer application for the pomodoro technique - hayato Google の面接試験で出る (はずがない)「海賊と金貨」問題を空気を読まないでプログラムで解いてみる - hayato hayato.io (4topcoder) - hayato SRM432 - hayato SRM405 - hayato SRM386 - hayato SRM385 - hayato SRM384 - ゲーム - hayato SRM369 - hayato SRM368 - hayato SRM366 - typo 2 連発 - hayato Python - generator で素数生成 - hayato New Launguage - 新言語追加の予定? - hayato lxml で HTML スクレーピング - hayato SRM358 - Today is a Bad Day (-50). - hayato SRM349 FizzBuzz 問題が簡単すぎるそんなあなたへ。「赤いマーブル問題」。 - hayato Suffix Array - hayato google-code-prettify を導入してみる - hayato Subset の生成 - hayato 2006 年のまとめ - SRM332 - hayato Google Code Jam 2006 - Championship Round - hayato Blogger Beta に移行 - hayato Google Code Jam 2006 - Round1 に挑戦 - Generics と AutoBoxing - hayato Google Code Jam 2006 - Qualification Round 通過 - hayato Google Code Jam 2006 - Qualification Round に挑戦 - hayato Google Code Jam 2006 - Practice1 - hayato Google Code Jam 2006 - 開催決定 - hayato Stay tuned... Global Google Code Jam 2006 - 秋に開催? - hayato SRM308 - Hard DP - hayato SRM304 - 条件付確率 - hayato JavaWorld に寄稿しました - hayato 2006 TopCoder Open Final Round - hayato IBM Rational Software Development Forum Tokyo で講演します - hayato SRM298 - ひとふで書き - hayato SRM293 - ビンゴ - hayato 2006 TopCoder Open - Round1 撃墜 - hayato 2006 TopCoder Open - Odds 発表 - hayato 2006 TopCoder Open Qualification Round - hayato デブサミ 2006 で講演します - hayato SRM287 - 気分は中学生?連立2元方程式 - hayato SRM281 - 2006 年はポイントゼロスタート - hayato SRM280 - Challenge 祭り - hayato SRM277 - 初賞金げっと - hayato マラソン・マッチ - hayato reStructuredText で blogger - hayato 2006 TopCoder Open - NSA がスポンサーに - hayato SRM276 - お買い物は楽しく DP で - hayato SRM273 - bit 演算は int で行われるのね - hayato SRM272 - Division1 - 4 度目の正直 - hayato JavaOne Tokyo で講演します - hayato SRM270 - Integer == Integer - hayato SRM268 - Division2 脱出 - hayato SRM266 - NASA, we have a problem... - hayato SRM265 - Division2 落ち... - hayato SRM262 - 初 Division1 は Typo に終わる - hayato SRM260 - TopCoder への挑戦のはじまり - hayato
SRM291 - OutOfMemory - hayato
2006-02-22 · via hayato

SRM291 に挑戦.

2006 TopCoder Open - Algorithm Competition が来週の 2 月 28 日から始まります.今日は,それに向けて最後の SRM になります.

250 点問題. 折り紙で雪の結晶をつくりましょう.

SRM291 Snowflakes From TopCoder

このように 8 等分に折った折り紙に対して,

SRM291 Snowflakes From TopCoder

穴をあけてから,もとの大きさに広げると,あら不思議.雪の結晶のように,対称な,きれいな形ができますねー.あ,そう.って感じですが,,,

問題は,以下のような,8 等分に折った折り紙の穴のパターンが与えられたとき,

{"*",
 "..",
 ".*.",
 ".**.",
 ".*.**"}

広げた形のパターンを求めてください.という問題です. 例の場合は,答えはこのようになります.

{"**.*..*.**",
 "*.**..**.*",
 ".*.*..*.*.",
 "***....***",
 "....**....",
 "....**....",
 "***....***",
 ".*.*..*.*.",
 "*.**..**.*",
 "**.*..*.**" }

悩むところは特にないですが,いかに時間をかけないでサクサクすませられるか勝負です.私は,14 分もかかってしまいましたが,早い人は,3 分かからずにすませています..

500 点問題. 素直に BFS でいけました.

1000 点問題. Level1,Level2 問題を終えた時点で,30 分ほど時間がありましたので,1000 点問題にチャレンジ.

単語(Word)がいくつか与えられます.

{"salad", "sandwich", "hamburger", "rings"}

これらの単語の最初の文字と最後の文字をつなげて,文字列をつくっていきます.

"hamburgeringsandwichamburger..."

「しりとり」ですね.こうしてできる文字列のうち,長さが (len) 以上のもので,辞書的に一番最初にくる文字列を返しなさい.という問題です.たとえば,入力が

{"abd", "dgga", "abdg", "gga", "gg", "gaader"}
len: 22

ならば,

"abdggabdggabdggabdgaader"

が答えになります.

ちょっと考え,「DP でいける!」と思い,コーディング開始. 1000 点問題をはじめて解けるか?! と思ったのですが,時間が足りませんでした.. SRM 後,悔しいので完成させました.

public class StickedWords {

  public String constructLine(String[] dict, int len) {

      String[][] dp = new String[len+51][26];
      for (int i = 1; i < dp.length; i++) {
          for (int j = 0; j < 26; j++) {
              for (String word : dict) {
                  if (word.charAt(word.length()-1) - 'a' != j) continue;
                  if (i == word.length()) {
                      if (dp[i][j] == null || word.compareTo(dp[i][j]) < 0) {
                          dp[i][j] = word;
                      }
                      continue;
                  }
                  int pre = i - (word.length() - 1);
                  if (pre <= 0) continue;
                  int first = word.charAt(0) - 'a';
                  if (dp[pre][first] == null) continue;
                  String next = dp[pre][first] + word.substring(1);
                  if (dp[i][j] == null || next.compareTo(dp[i][j]) < 0) {
                      dp[i][j] = next;
                  }
              }
          }
      }
      String res = null;
      for (int i = len; i < len+51; i++) {
          for (int j = 0; j < 26; j++) {
              if (dp[i][j] == null) continue;
              if (res == null || dp[i][j].compareTo(res) < 0) {
                  res = dp[i][j];
              }
          }
      }
      return (res == null) ? "" : res;
  }
}

もうちょっとだったのになーと思っていたけど,実は,ぜんぜんもうちょっとではありませんでした.落とし穴がまっていました.. 最悪のケース (len=2500)では,

java.lang.OutOfMemoryError...

を引き起こしてしまいます. TopCoder では時間(2 秒以内)という制限だけではなく,使用メモリの制限 (64Mbyte)もありました. 最悪のケース (len=2500)では,最終的にはメモリ使用量は,

2500 x (2500 / 2) x 26 = 81250000

ですから,80MByte を超えますね...これはトリッキーだ..普通,気づかないよな.. 1000 点問題にしてはとっかかりやすいと思ったけど,こういう側面があったとは..こういうのは,問題作成者が意図的にやってるんですね.

ひとつあたりの単語の長さは最大 50 なので,DP をしつつ,最近の 50 ステップ分だけ,覚えるようにして,いらなくなったものには,null をいれると.

}
if (i - 51 >= 0) {
    dp[i-51] = null;
}

これで,なんとか System Test に通るようになります.

結果

System Test の結果です. ( Room Statistics )

Room Statistics

レーティングは 1626 -> 1730 と 100 ほど上昇しました.いよいよ来週は,2006 TopCoder Open の予選です.

今日の教訓

  • メモリ使用量に注意.