2010年5月23日日曜日

Google Code Jam 2010 Round 1B

■問題A
既に作られているディレクトリ構造と,これから作ろうとしているディレクトリ構造が与えられる.mkdirコマンドは何回実行する必要があるか.


□解法A
実装ゲー.ちまちましたミスでかなり手間取ってしまいました.

import java.io.*;
import java.util.*;

public class A {

class Node{
HashMap<String, Node> children=new HashMap<String, Node>();
}

long cal(int N, int M, String[] exist, String[] create){
Node root=new Node();

for(int i=0;i<N;i++){
String[] s=exist[i].split("/");
Node node=root;
for(int k=1;k<s.length;k++){
if(!node.children.containsKey(s[k]))
node.children.put(s[k], new Node());
node=node.children.get(s[k]);
}
}

long ret=0;
for(int i=0;i<M;i++){
String[] s=create[i].split("/");
Node node=root;
for(int k=1;k<s.length;k++){
if(!node.children.containsKey(s[k])){
ret++;
node.children.put(s[k], new Node());
}
node=node.children.get(s[k]);
}
}

return ret;
}

void a() throws Exception{
Scanner sc=new Scanner(new FileReader("D:\\google_code_jam\\gcj2010\\round1b\\a\\A-large.in"));
BufferedWriter bw=new BufferedWriter(new FileWriter("D:\\google_code_jam\\gcj2010\\round1b\\a\\A-large.out"));

int T=sc.nextInt();
for(int k=0;k<T;k++){
int N=sc.nextInt();
int M=sc.nextInt();
sc.nextLine();

String[] exist=new String[N];
for(int i=0;i<N;i++)
exist[i]=sc.nextLine();

String[] create=new String[M];
for(int i=0;i<M;i++)
create[i]=sc.nextLine();

long ans=cal(N,M,exist,create);
System.out.println("Case #"+(k+1)+": "+ans);
bw.write("Case #"+(k+1)+": "+ans);
bw.newLine();
}
bw.close();
}
}


■問題B
沢山のヒヨコちゃんがレール上にいる.それぞれのヒヨコはある方向に走っており,後方のヒヨコちゃんは,前方のヒヨコちゃんに追いついてしまったら,前方のヒヨコちゃんと同じ速度に減速する.また,クレーンを使って隣り合う2匹のヒヨコちゃんを交換することが出来る.N匹のヒヨコに対し,初期位置xi[m]と速度vi[m/s]が与えられる.K(≦N)匹のヒヨコがT[s]以内でB[m]の地点に到達するように,クレーンでヒヨコを移動させた時,その最小回数はいくらか.


□解法B
ヒヨコ?クレーン?といった感じで,問題文を理解するのにかなりの時間が掛かってしまいました.分かった後はこれまた実装ゲー.

import java.io.*;
import java.util.*;

public class B {

String cal(int N,int K,long B,int T,int[] x,int[] v){
boolean[] barn=new boolean[N];
int nBarn=0;
for(int i=0;i<N;i++){
int p=x[i]+v[i]*T;
if(p>=B)
nBarn++;
barn[i]=p>=B;
}
if(nBarn<K)
return "IMPOSSIBLE";

int pick=0;
int j=N;
for(int k=0;k<K;k++){
while(!barn[--j]);
for(int i=j;i+1<N&&!barn[i+1];i++){
boolean f=barn[i];
barn[i]=barn[i+1];
barn[i+1]=f;
pick++;
}
}

return ""+pick;
}

void a() throws Exception{
Scanner sc=new Scanner(new FileReader("D:\\google_code_jam\\gcj2010\\round1b\\b\\B-large.in"));
BufferedWriter bw=new BufferedWriter(new FileWriter("D:\\google_code_jam\\gcj2010\\round1b\\b\\B-large.out"));

int C=sc.nextInt();
for(int k=0;k<C;k++){
int N=sc.nextInt();
int K=sc.nextInt();
long B=sc.nextLong();
int T=sc.nextInt();
int[] x=new int[N];
int[] v=new int[N];

for(int i=0;i<N;i++)
x[i]=sc.nextInt();
for(int i=0;i<N;i++)
v[i]=sc.nextInt();

String ans=cal(N,K,B,T,x,v);
System.out.println("Case #"+(k+1)+": "+ans);
bw.write("Case #"+(k+1)+": "+ans);
bw.newLine();
}
bw.close();
}

}


■問題C
a1, …, ak=nという数列がある.nはk番目,kはi番目,iはj番目,…という操作の結果,最終的にa1は1番目,となるような数列はいくつあるか.与えられる数はnのみ.


□解法C
コーディングが間に合わず.

■結果
ABC
small○(12)○(13)×(14)
large○(14)○(17)×(30)
point26300

56Point,1257位.

1000位以内に入れなかったのでRound2に進めず….18:00からのRound1Cで1000位以内に入れなかったら敗退.

0 件のコメント: