<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>寝る前にラーメン &#187; Algorithm</title>
	<atom:link href="http://thleave.com/tag/algorithm/feed" rel="self" type="application/rss+xml" />
	<link>http://thleave.com</link>
	<description>学生エンジニアのコードに関する忘備録</description>
	<lastBuildDate>Mon, 30 Aug 2010 15:41:01 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Google Code Jam 2010 Round1B</title>
		<link>http://thleave.com/contests/271</link>
		<comments>http://thleave.com/contests/271#comments</comments>
		<pubDate>Tue, 25 May 2010 06:36:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[プログラミングコンテスト]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[CodeJam]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://thleave.com/?p=271</guid>
		<description><![CDATA[1Aは寝坊しました！
最近実務ばかりで、PHPしか書いてないから最初戸惑ったが、、、Javaバンザイ。
Google Code Jam 2010 is in Dublin!
http://code.google.com/ [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>1Aは寝坊しました！<br />
最近実務ばかりで、PHPしか書いてないから最初戸惑ったが、、、Javaバンザイ。</p>
<p><strong>Google Code Jam 2010 is in Dublin!</strong><br />
<a href="http://code.google.com/codejam">http://code.google.com/codejam</a></p>
<p><span id="more-271"></span></p>
<h3>File Fix-it</h3>
<p>Unixのディレクトリー構造。知ってることが問題だと楽。<br />
mkdirの-pオブションをつけずにディレクトリーを作っていく場合の手数を出す。<br />
Largeでもmax(N)=max(M)=100なので、JavaならばHashSetですぐ。</p>
<h3>Picking Up Chicks</h3>
<p>最初問題の意味がさっぱり分からなかった。<br />
チキンをどうするんだ！チキンを！</p>
<p>相当悩む。テストケース見て意味を探る。<br />
Kの意味の理解に苦しんだ。<br />
最低限スワップする数？？や、この数だけチキンが来ればいいんだ！（ここでアハ体験）<br />
（ここで30分以上かかった）</p>
<p>問題の解釈。</p>
<ul>
<li>（スワップしなければ）並び順通りにゴールしていく！入力が優しい。</li>
<li>順に見ていくうちに時間過ぎたら、それ以降の奴らはスワップしない限り間に合わない</li>
<li>（それでもKに満たないならば、）後ろにいる時間内にゴールできるやつを前に出す。<br />
抜いた分だけがコスト</li>
<li>後ろまでみてKに満たないならばそれはミッションインポッシブル！</li>
</ul>
<p>ここからは書くだけ。<br />
スワップを何で実装しようか迷ったけど、せっかくJavaなんだからLinkedList使うことにした。<br />
[java]<br />
LinkedList<Double> time = new LinkedList<Double>();<br />
// 先頭に追加<br />
time.addFirst(t);<br />
// jに追加<br />
time.add(j, target);<br />
// jを削除<br />
time.remove(j);<br />
[/java]<br />
なんてらくちんな。</p>
<h3>Your Rank is Pure</h3>
<p>やー、全く問題の意味がわからなかった。<br />
なにこれ？<br />
サンプルも２つしか載ってないし。<br />
まだ１時間以上残ってたけど全く解ける気がしなかった。</p>
<p>30分切ったくらいで諦める。2問解いて56pだしいけるんじゃない？って。<br />
したら、みんなsmallはどんどん解いていく。。。どこをどう解釈したら？？</p>
<p>それでも解けないでモヤモヤしてたら終了！その時点で1070位前後。あー。<br />
largeでどれだけ落ちるかと期待したけれど、結果1010位！あと9人！！あと1分ちょい早ければ！！！</p>
<p>これはすげーへこんだ。。<br />
なので、次の日あるのにチャンピオンズリーグを見てしまいましたとさ！<br />
（この終了時間は絶対CL決勝を意識したんだろう！と思ってしまう笑）</p>
<p>1Cは出られなかったので、これで今年のGCJは終わり。<br />
来年また頑張ります。</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://thleave.com/contests/271/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>漸近的計算量と計算時間の相関</title>
		<link>http://thleave.com/coding/256</link>
		<comments>http://thleave.com/coding/256#comments</comments>
		<pubDate>Tue, 11 May 2010 15:06:45 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://thleave.com/?p=256</guid>
		<description><![CDATA[GoogleCodeJamのQualificationに参加してみて、
どのくらいまでのオーダーの計算量ならコンテスト中に処理できるのか
気になったので簡単なプログラムを作って計測してみました。

テストに使ったのはこん [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>GoogleCodeJamのQualificationに参加してみて、<br />
どのくらいまでのオーダーの計算量ならコンテスト中に処理できるのか<br />
気になったので簡単なプログラムを作って計測してみました。</p>
<p><span id="more-256"></span></p>
<p>テストに使ったのはこんなコード。<br />
ぐちゃぐちゃだけど気にしないで！<br />
[java]<br />
	public static void main(String[] args) {<br />
		for (int order = 1; order <= 15; order++) {<br />
			long start = System.currentTimeMillis();<br />
			long temp = 0;<br />
			long end = (long) Math.pow(10, order);<br />
			for (long i = 0; i < end; i++) {<br />
				if (i % 2 == 0) {<br />
					temp -= i;<br />
				} else {<br />
					temp += i;<br />
				}<br />
			}</p>
<p>			long diff = System.currentTimeMillis() - start;<br />
			System.out.printf("O(10^%d) %d:%02d.%04d\n", order, diff / 1000 / 60, diff / 1000 % 60, diff % 1000);<br />
		}</p>
<p>	}<br />
[/java]</p>
<p>以下が出力結果ですー！</p>
<p>[text]<br />
O(10^1) 0:00.0000<br />
O(10^2) 0:00.0000<br />
O(10^3) 0:00.0000<br />
O(10^4) 0:00.0000<br />
O(10^5) 0:00.0000<br />
O(10^6) 0:00.0026<br />
O(10^7) 0:00.0438<br />
O(10^8) 0:04.0543<br />
O(10^9) 0:46.0106<br />
O(10^10) 7:43.0682<br />
[/text]</p>
<ul>
<li>O(10^7)までは計算量と時間に一応の相関関係はみえる。一応の。</li>
<li>O(10^8)までがコンテストなら許容範囲かな？</li>
<li>O(10^8)からは計算量と時間にはっきりと比例関係がみえる。</li>
<li>O(10^5)まではミリ秒単位でもゼロ！改めてコンピュータの計算力って凄いね。</li>
</ul>
<p>コンパイラのバージョンはjdk1.6でした。<br />
もちろん計測するコンピュータによって結果が変わってくると思うので参考程度に使ってください。</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://thleave.com/coding/256/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>幅優先探索をJavaを使って覚える</title>
		<link>http://thleave.com/coding/218</link>
		<comments>http://thleave.com/coding/218#comments</comments>
		<pubDate>Sat, 16 Jan 2010 16:59:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://thleave.com/?p=218</guid>
		<description><![CDATA[下らない内容だなぁと思い人もたくさんいるかと思いますが、
自分は今まで幅優先探索が苦手で敬遠してきました！(笑
そんなお仲間がいらっしゃればご参考になればと。
この記事はそれ以上でもそれ以下でもございません。

まず、き [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>下らない内容だなぁと思い人もたくさんいるかと思いますが、<br />
自分は今まで幅優先探索が苦手で敬遠してきました！(笑</p>
<p>そんなお仲間がいらっしゃればご参考になればと。<br />
この記事はそれ以上でもそれ以下でもございません。</p>
<p><span id="more-218"></span></p>
<p>まず、きっかけです。<br />
最近いろいろなところで目にしたので、是非解きたいと思った問題がありまして、、</p>
<p>人材獲得作戦・４　試験問題ほか | 人生を書き換える者すらいた。<br />
<a href="http://okajima.air-nifty.com/b/2010/01/post-abc6.html">http://okajima.air-nifty.com/b/2010/01/post-abc6.html</a></p>
<p>これなんですが、読んでみたら簡単そうなんですが、どうやら幅優先探索(BFS:BreadthFirstSearch)を使いそう。<br />
TopCoderでは、「BFSがベストアンサー！」みたいな問題は今まで見かけなかったので放置していたんですが、<br />
腹をくくって勉強。<br />
DFSは得意なんだよね。なぜか、あの再帰具合が。</p>
<p>で、たまたまITMediaで連載中の講座でも探索が！<br />
これは偶然だけども。</p>
<p>知れば天国、知らねば地獄――「探索」虎の巻 | 最強最速アルゴリズマー養成講座<br />
<a href="http://www.itmedia.co.jp/enterprise/articles/1001/16/news001.html">http://www.itmedia.co.jp/enterprise/articles/1001/16/news001.html</a></p>
<p>探索は基本だよねえ。うん。</p>
<h3>Javaでの実装に使うもの</h3>
<p>そこを読ませて頂いても、Wikipediaの解説を読んでも、キュー(Queue)を使うのが基本らしい。<br />
幅優先っていう概念はわかりやすいんだけどね。実装がねー</p>
<p>JavaでQueueだと、Queueインターフェイスを実装した<a href="http://java.sun.com/javase/ja/6/docs/ja/api/java/util/LinkedList.html">LinkedList</a>なんかがお手頃。<br />
※ 話が逸れるけど、Eclipseで「LLi」ってとこまでいれて保管すると一番上にLinkedListがでる。</p>
<p>で、問題はなんのメソッドを使うか。<br />
Stackインターフェイスも実装しているからややこしいんだけど、<br />
Queueは先入れ先出し(FIFO)が原則なので、後方から入れて先頭から出すようにする。<br />
行列と同じ。以下の２つのメソッドを使う。</p>
<p><strong>LinkedList#offer(e)</strong><br />
リストの末尾に追加。</p>
<p><strong>LinkedList#poll()</strong><br />
リストの先頭を取得して削除。</p>
<p>Stackに関係するメソッドは有名だから知ってたけど、<br />
この２つは最近まで全然知らなかった。（のは俺だけかもしれない）</p>
<h3>実装</h3>
<p>後は書くしか無い。</p>
<p>ALGORITHM NOTE | 幅優先探索 Breadth First Search<br />
<a href="http://algorithms.blog55.fc2.com/blog-entry-127.html">http://algorithms.blog55.fc2.com/blog-entry-127.html</a></p>
<p>参考にしました。このサイトにはいつも助けられてます。</p>
<p>自分で分かりやすく書きたかったので、結構だらだら長いコードだけど、こんな感じ。<br />
[java]<br />
public class BreadthFirstSearch {<br />
	Point[] move = new Point[]{new Point(0, -1), new Point(-1,0), new Point(1, 0), new Point(0,1)};<br />
	char[] directions = new char[]{&#8216;r&#8217;, &#8216;d&#8217;, &#8216;u&#8217;, &#8216;l&#8217;};</p>
<p>	public BreadthFirstSearch(int[][] input, int sx, int sy){<br />
		class Puzzle {<br />
			int[][] map = new int[3][3];<br />
			int x = 0;<br />
			int y = 0;<br />
			String path;</p>
<p>			public Puzzle(int[][] map, int x, int y, String path) {<br />
				this.map = map;<br />
				this.x = x;<br />
				this.y = y;<br />
				this.path = path;<br />
			}</p>
<p>			public boolean check(){<br />
				for (int i = 0; i < 8; i++) {<br />
					if (this.map[i / 3][i % 3] != i+1) return false;<br />
				}<br />
				return true;<br />
			}<br />
		}</p>
<p>		LinkedList<Puzzle> queue = new LinkedList<Puzzle>();<br />
		queue.push(new Puzzle(input, sx, sy, &#8220;&#8221;));</p>
<p>		BFS : while (queue.size() > 0) {<br />
			Puzzle p = queue.poll();</p>
<p>			for (int i = 0; i < 4; i++) {<br />
				int x = p.x + move[i].x;<br />
				int y = p.y + move[i].y;</p>
<p>				if (x >= 0 &#038;&#038; x <= 2 &#038;&#038; y >= 0 &#038;&#038; y <= 2) {<br />
					int[][] map = this.dc(p.map);<br />
					map[p.x][p.y] = map[x][y];<br />
					map[x][y] = 0;</p>
<p>					Puzzle moved = new Puzzle(map, x, y, p.path + directions[i]);<br />
					if (moved.check()) {<br />
						System.out.println(moved.path);<br />
						break BFS;<br />
					}</p>
<p>					queue.add(moved);<br />
				}<br />
			}<br />
		}</p>
<p>		System.out.println("#END");<br />
	}</p>
<p>	public int[][] dc(int[][] input){<br />
		int[][] output = new int[input.length][input[0].length];<br />
		for (int i = 0; i < input.length; i++) {<br />
			output[i] = input[i].clone();<br />
		}<br />
		return output;<br />
	}</p>
<p>	public static void main(String[] args) throws FileNotFoundException {<br />
		FileInputStream fis = new FileInputStream("src/study/puzzle.in");<br />
		Scanner sc = new Scanner(fis);</p>
<p>		int[][] puzzle = new int[3][3];<br />
		int x = 0;<br />
		int y = 0;</p>
<p>		for (int i = 0; i < 9; i++) {<br />
			char input = sc.next().charAt(0);<br />
			if (input == 'x') {<br />
				x = i / 3;<br />
				y = i % 3;<br />
				puzzle[i / 3][i % 3] = 0;<br />
			} else {<br />
				puzzle[i / 3][i % 3] = input - '0';<br />
			}<br />
		}</p>
<p>		new BreadthFirstSearch(puzzle, x, y);<br />
	}<br />
}</p>
<p>[/java]</p>
<p>次に本命のあのサイト。<br />
せっかくだからTopCoderっぽくコストから出してみた。<br />
かなり回りくどいけど、書いてて自分で勉強になった。</p>
<p>[java]<br />
public class Kuma4_1 {<br />
	static final int width = 26;<br />
	static final int height = 13;<br />
	Point[] movable = new Point[]{new Point(1, 0), new Point(0, 1), new Point(-1, 0), new Point(0, -1)};</p>
<p>	public Kuma4_1(char[][] map, int sx, int sy, int gx, int gy) {<br />
		LinkedList<Point> queue = new LinkedList<Point>();<br />
		queue.add(new Point(sx, sy));<br />
		int cost = 1;<br />
		int[][] costMap = new int[height][width];<br />
		char[][] copiedMap = this.dc(map);</p>
<p>		BFS: while (queue.size() > 0) {<br />
			Point now = queue.poll();</p>
<p>			for (int i = 0; i < movable.length; i++) {<br />
				int x = now.x + movable[i].x;<br />
				int y = now.y + movable[i].y;</p>
<p>				if (map[x][y] == 'G') {<br />
					costMap[x][y] = cost;<br />
					this.out(copiedMap, costMap, gx, gy);<br />
					break BFS;</p>
<p>				} else if (map[x][y] == ' ') {<br />
					costMap[x][y] = cost;<br />
					map[x][y] = '#';<br />
					queue.offer(new Point(x,y));<br />
				}<br />
			}</p>
<p>			cost++;<br />
		}</p>
<p>		System.out.println("#process end");<br />
	}</p>
<p>	public void out(char[][] map, int[][] costMap, int gx, int gy){<br />
		int cost = costMap[gx][gy];<br />
		Point p = new Point(gx, gy);<br />
		while (cost > 1){<br />
			cost&#8211;;<br />
			for (int i = 0; i < movable.length; i++) {<br />
				int x = p.x + movable[i].x;<br />
				int y = p.y + movable[i].y;</p>
<p>				if (costMap[x][y] == cost) {<br />
					map[x][y] = &#8216;$&#8217;;<br />
					p = new Point(x,y);<br />
				}<br />
			}<br />
		}</p>
<p>		for (int i = 0; i < map.length; i++) {<br />
			System.out.println(new String(map[i]));<br />
		}<br />
	}</p>
<p>	public void out(int[][] map) {<br />
		for (int i = 0; i < map.length; i++) {<br />
			for (int j = 0; j < map[i].length; j++) {<br />
				System.out.printf(&#8220;%3d&#8221;, map[i][j]);<br />
			}<br />
			System.out.println();<br />
		}<br />
	}</p>
<p>	public void out(char[][] map) {<br />
		for (char i = 0; i < map.length; i++) {<br />
			System.out.println(new String(map[i]));<br />
		}<br />
	}</p>
<p>	public char[][] dc(char[][] input){<br />
		char[][] output = new char[input.length][input[0].length];<br />
		for (char i = 0; i < input.length; i++) {<br />
			output[i] = input[i].clone();<br />
		}<br />
		return output;<br />
	}</p>
<p>	public static void main(String[] args) throws FileNotFoundException {<br />
		FileInputStream fis = new FileInputStream(&#8220;src/study/kuma4.in&#8221;);<br />
		Scanner sc = new Scanner(fis);</p>
<p>		char[][] map = new char[height][width];</p>
<p>		for (int i = 0; sc.hasNext(); i++) {<br />
			String line = sc.nextLine();<br />
			map[i] = line.toCharArray();<br />
		}</p>
<p>		int sx=0, sy=0, gx=0, gy=0;<br />
		for (int i = 0; i < map.length; i++) {<br />
			for (int j = 0; j < map[0].length; j++) {<br />
				if (map[i][j] == &#8216;S&#8217;) {<br />
					sx = i;<br />
					sy = j;<br />
				} else if (map[i][j] == &#8216;G&#8217;) {<br />
					gx = i;<br />
					gy = j;<br />
				}<br />
			}<br />
		}</p>
<p>		new Kuma4_1(map, sx, sy, gx, gy);<br />
	}<br />
[/java]</p>
<p>しかしなげぇ。でも、書く時間自体はそんなかからなかった。30分弱くらいかなあ。<br />
でも、アルゴリズム調べてからだから、そう考えると論外だとも。</p>
<p>とにかく、ぼくはこれで幅優先探索をやっと覚えました！ばっちこい。</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://thleave.com/coding/218/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
