ラベル TopCoder の投稿を表示しています。 すべての投稿を表示
ラベル TopCoder の投稿を表示しています。 すべての投稿を表示

2011年4月18日月曜日

BottomCoder SRM398 DIV2

下書きのままだったので公開する。

昔過ぎてもう問題覚えてない。
たしかこれはどっちも解けたはず。

import java.util.Arrays;

public class MinDifference {
 public double EPS = 1e-6;
 
 public int closestElements(int A0, int X, int Y, int M, int n) {
  int[] a = new int[n];
  a[0] = A0;
  for(int i = 1; i < n; i++) {
   a[i] = (a[i - 1] * X + Y) % M;
  }
  Arrays.sort(a);
  int res = Integer.MAX_VALUE;
  for(int i = a.length - 1; i > 0; i--) {
   res = Math.min(res, a[i] - a[i - 1]);
  }
  return res;
 }
 
 public void tr(Object... o) { System.out.println(o.length > 1 || o[0].getClass().isArray() ? Arrays.deepToString(o) : o[0]); }
}


激しい。
こんなことしなくても解ける・・・
import java.util.Arrays;
import java.util.LinkedList;

public class CountExpressions {
 public double EPS = 1e-6;
 
 private LinkedList list = new LinkedList();
 private int res = 0;
 private int ans;
 
 public int calcExpressions(int x, int y, int val) {
  ans = val;
  
  list.add(x);
  list.add(x);
  list.add(y);
  list.add(y);
  dfs("+", 0, list.poll(), 0);
  
  list = new LinkedList();
  list.add(x);
  list.add(y);
  list.add(x);
  list.add(y);
  dfs("+", 0, list.poll(), 0);

  list = new LinkedList();
  list.add(x);
  list.add(y);
  list.add(y);
  list.add(x);
  dfs("+", 0, list.poll(), 0);

  list = new LinkedList();
  list.add(y);
  list.add(y);
  list.add(x);
  list.add(x);
  dfs("+", 0, list.poll(), 0);

  list = new LinkedList();
  list.add(y);
  list.add(x);
  list.add(x);
  list.add(y);
  dfs("+", 0, list.poll(), 0);

  list = new LinkedList();
  list.add(y);
  list.add(x);
  list.add(y);
  list.add(x);
  dfs("+", 0, list.poll(), 0);
  
  tr(res);
  return res;
 }
 
 private void dfs(String s, long val, int v, int n) {
  if(s.equals("+")) {
   val += (long)v;
  } else if(s.equals("-")) {
   val -= (long)v;
  } else {
   val *= (long)v;
  }
  
  if(n > 2) {
   if(val == ans) {
    res++;
   }
   list.add(0, v);
   return;
  }

  dfs("+", val, list.poll(), n + 1);
  dfs("-", val, list.poll(), n + 1);
  dfs("*", val, list.poll(), n + 1);
  list.add(0, v);
 }
 
 public void tr(Object... o) { System.out.println(o.length > 1 || o[0].getClass().isArray() ? Arrays.deepToString(o) : o[0]); }
}

2010年12月25日土曜日

BottomCoder SRM403 DIV2

これからは本番はTopCoderってタイトルで、練習はBottomCoderってタイトルにします。
最近TopCoderの記事が多いのでもっとほかの記事も書きたいです。

250
public class TheLargestLuckyNumber {
 public int find(int n) {
  outer: for(int i = n; i >= 4; i--) {
   for(int j = 0; j < Integer.toString(i).length(); j++) {
    if(Integer.toString(i).charAt(j) != '7' && Integer.toString(i).charAt(j) != '4') {
     continue outer;
    }
   }
   return i;
  }
  
  return 0;
 }
}
早く解けた。2重ループだとラベル便利。

500
public class TheLuckyNumbers {
 public int count(int a, int b) {
  int count = 0;
  String sa = Integer.toString(a);
  String sb = Integer.toString(b);
  int len = sb.length();
  for(int j = 1; j <= len; j++) {
   for(int mask = 0; mask < (1 << j); mask++) {
    String str = "";
    for(int i = 0; i < j; i++) {
     if((mask & (1 << i)) > 0) {
      str += "7";
     } else {
      str += "4";
     }
    }
    if((str.length() > sa.length() || (str.length() == sa.length() && str.compareTo(sa) >= 0)) && (str.length() < sb.length() || str.compareTo(sb) <= 0)) {
     count++;
    }
   }
  }
  return count;
 }
}
250のように全探索すると、2秒以内に終わらないので計算量を減らす必要がある問題。
いろいろな解き方でアプローチしてて時間内に終わらなかった。
自力で解くことはできたけど、これぐらいの問題を解けないと緑安定はしないし、解けるようになりたい。
roseとlilyのときにも使ったビットを使った方法で解いてます。この問題は解き方いくつかありそう。

2010年12月14日火曜日

TopCoder練習 SRM424 DIV2

250問題文
public class MagicSpell {
 public String fixTheSpell(String spell) {
  String magic = new String();
  for(int i = 0; i < spell.length(); i++) {
   if(spell.charAt(i) == 'A' || spell.charAt(i) == 'Z') {
    magic += spell.charAt(i);
   }
  }
  String magicSpell = new String();
  int count = 0;
  for(int i = 0; i < spell.length(); i++) {
   if(spell.charAt(i) == 'A' || spell.charAt(i) == 'Z') {
    magicSpell += magic.charAt(magic.length()-1-count);
    count++;
   } else {
    magicSpell += spell.charAt(i);
   }
  }
  return magicSpell;
 }
}
問題文が読めれば解ける。コードは汚い。

500

import java.util.ArrayList;

public class ProductOfDigits {
 public int smallestNumber(int N) {
  if(N < 10) return 1;
  
  ArrayList<Integer> list = new ArrayList<Integer>();
  for(int i = 9; i > 1; i--) {
   if(N % i == 0) {
    list.add(i);
   }
  }
  if(list.size() < 1) return -1;
  
  int index = 0;
  int a = 0;
  while(N > 1) {
   if(N % list.get(index) == 0) {
    a++;
    N /= list.get(index);
   } else {
    if(index < list.size() -1) {
     index++;
    } else {
     return -1;
    }
   }
  }
  return a;
 }
}
問題文の意味よく分からなくて1文字もかけなかった。

2010年12月13日月曜日

TopCoder練習 SRM 423 DIV2

250問題文
public class TheSimpleGame {
 public int count(int n, int[] x, int[] y) {
  int a = (n+1)/2;
  int b = 0;
  for(int i = 0; i < x.length; i++) {
   b += (x[i] <= a) ? x[i] - 1 : n - x[i];
   b += (y[i] <= a) ? y[i] - 1 : n - y[i];
  }
  return b;
 }
}
簡単。

600
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

public class TheTower {
 public int[] count(int[] x, int[] y) {
  int[] a = new int[x.length];
  a[0] = 0;
  if(x.length == 1) {
   return a;
  }
  ArrayList<Integer> xList = new ArrayList<Integer>();
  ArrayList<Integer> yList = new ArrayList<Integer>();
  for(int i = 0; i < x.length; i++) {
   boolean flag1 = false;
   boolean flag2 = false;
   for(int j = 0; j < xList.size(); j++) {
    if(x[i] == xList.get(j)) {
     flag1 = true;
     break;
    }
   }
   if(!flag1) {
    xList.add(x[i]);
   }
   for(int j = 0; j < yList.size(); j++) {
    if(y[i] == yList.get(j)) {
     flag2 = true;
     break;
    }
   }
   if(!flag2) {
    yList.add(y[i]);
   }
  }
  for(int i = 1; i < x.length; i++) {
   ArrayList<Integer> list = new ArrayList<Integer>();
   for(int j = 0; j < xList.size(); j++) {
    for(int k = 0; k < yList.size(); k++) {
     list.add(checkCell(xList.get(j), yList.get(k), i+1, x, y));
    }
   }
   Collections.sort(list);
   a[i] = list.get(0);
  }
  return a;
 }
 
 private int checkCell(int x, int y, int n, int[] arrayX, int[] arrayY) {
  int[] array = new int[arrayX.length];
  for(int i = 0; i < array.length; i++) {
   array[i] = (int)Math.abs((double)(x - arrayX[i])) + (int)Math.abs((double)(y - arrayY[i]));
  }
  Arrays.sort(array);
  int move = 0;
  for(int i = 0; i < n; i++) {
   move += array[i];
  }
  return move;
 }
}
間違えたので後で修正した解答。
問題文は読めても結構難しい問題だと思う。これが600か。
おそらく、移動先のx,yはそれぞれのメジアン(中央値)になる。(ただしチェッカーが偶数のときは中央2つの平均ではなく、その2つのどちらかになる
そう考えると、x座標のリストと、y座標のリストの組み合わせ分だけ考慮すればいいので、その中で一番移動数が少ないものを選ぶ。

TopCoder SRM490 DIV2

2回目。落ち込む。チャレンジやってみたくてやったけど失敗した。
250 ○
500 未提出
1000 未提出
Rate 955 -> 789

TopCoder SRM489 DIV2

初めてのTopCoder本番ってわけだったんですが、結果は何とも言えないものにw
250 チャレンジ
500 未提出
1000 未提出

1問も解けなく、点数はもちろん0なわけですが、レートは955というそれなりに高いという結果に。いきなり緑。
どうやら250の正解率が低かったみたい。

2010年11月25日木曜日

TopCoder練習 SRM420 DIV2

250 問題文(要ログイン)
public class DeckRearranging {
 public String rearrange(String deck, int[] above) {
  String a = new String();
  for(int i = 0; i < deck.length(); i++) {
   a = a.substring(0, above[i]) + String.valueOf(deck.charAt(i)) + a.substring(above[i]);
  }
  return a;
 }
}
簡単。
500 問題文(要ログイン)
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

public class YearProgressbar {
 public double percentage(String currentDate) {
  SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy HH:mm z", Locale.US);
  Date date = sdf.parse(currentDate + " EST", new ParsePosition(0));
  
  GregorianCalendar current = new GregorianCalendar();
  current.setTime(date);
  
  int year = current.get(GregorianCalendar.YEAR);
  GregorianCalendar start = new GregorianCalendar();
  String s = "January 01, " + Integer.toString(year) + " 00:00 EST";
  start.setTime(sdf.parse(s, new ParsePosition(0)));
  
  GregorianCalendar end = new GregorianCalendar();
  s = "January 01, " + Integer.toString(year + 1) + " 00:00 EST";
  end.setTime(sdf.parse(s, new ParsePosition(0)));
  
  return (double)(current.getTimeInMillis() - start.getTimeInMillis()) / (double)(end.getTimeInMillis() - start.getTimeInMillis()) * 100.0;
 }
}
今までで一番苦労しました。せっかくJavaを使っているんだからってCalendarクラスを使おうとした結果がこれだよ!

もう自分で実装したほうが早かったね・・・

ローカルではTestCaseが通るのに、TopCoder側では通らないという謎。
1時間以上悩んだ結果、原因は「夏時間」。
調べるうちにDateFormatクラスがあるから使ってやんよ、と思ったらこれもまた苦戦。
今度はローカルでSimpleDateFormatが動かない。なぜかTopCoder側で動く。
これは、Localeを指定しないと、月(Mayとか)を正しくとってこられないっぽい。デフォルトのままだと「5月」みたいに日本語表示しか読み取れなかったみたい。
そして、setTime(Date)した後は、setTimeZone(TimeZone)しても適用されていなくて、もうしょうがないから入力テキストにESTって記述してタイムゾーン指定してやったよ!!

他の人の解凍を見るとDateクラスの非推奨のメソッド使うともっと簡単にできたっぽい。もうやだ。

2010年11月20日土曜日

TopCoder練習 SRM425 DIV2

250
問題文(要ログイン)
import java.util.Arrays;

public class InverseFactoring {
 public int getTheNumber(int[] factors) {
  if(factors.length == 1) return factors[0]*factors[0];
  Arrays.sort(factors);
  return factors[0]*factors[factors.length-1];
 }

}
問題読めたもん勝ち。最初のif文は別に書かなくてもいい。
とても簡単。

500
問題文
public class CrazyBot {
 private boolean point[][] = new boolean[30][30];
 private double _east;
 private double _west;
 private double _north;
 private double _south;
 private double result = 0.0;
 
 public double getProbability(int n, int east, int west, int south, int north) {
  for(int i = 0; i < 30; i++) {
   for(int j = 0; j < 30; j++) {
    point[i][j] = false;
   }
  }
  _east = (double)east;
  _west = (double)west;
  _north = (double)north;
  _south = (double)south;
  dfs(n, 0, 0, 1.0);
  return result;
 }
 
 private void dfs(int n, int x, int y, double p) {
  if(point[y+15][x+15]) {
   return;
  }
  if(n == 0) {
   result += p;
   return;
  }
  point[y+15][x+15] = true;
  dfs(n-1, x+1, y, p*_east/100.0);
  dfs(n-1, x-1, y, p*_west/100.0);
  dfs(n-1, x, y+1, p*_north/100.0);
  dfs(n-1, x, y-1, p*_south/100.0);
  point[y+15][x+15] = false;
 }
}
この問題は時間内に解けなくて、人の回答を参考にした。
問題文読んでDFS(深さ優先探索)使えばいいんだなーって思ったけどどう実装していいかわからなかった。明らかな実力不足。勉強になりました。

2010年11月17日水曜日

TopCoder練習 SRM 422 DIV2

250
問題文(要ログイン)
public class MultiNumber {
 public String check(int number) {
  if(number < 10) {
   return "NO";
  }
  String num = Integer.toString(number);
  //String.valuOf(number);
  for(int i = 1; i < num.length(); i++) {
   String a = num.substring(0, i);
   String b = num.substring(i);
   int n = 1, m = 1;
   for(int j = 0; j < a.length(); j++) {
    n *= Integer.parseInt(a.substring(j, j+1));
   }
   for(int j = 0; j < b.length(); j++) {
    m *= Integer.parseInt(b.substring(j, j+1));
   }
   if(n == m) {
    return "YES";
   }
  }
  return "NO";
 }
}
Javaでint→StringとString→intの変換する方法がわからなくて手間取った。 今気づいたけど、このプログラムちょっと無駄なことしてるね。

500
問題文
public class PrimeSoccer {
 public double getProbability(int skillOfTeamA, int skillOfTeamB) {
  double a = 0.0;
  double b = 0.0;
  //2
  a += ((double)skillOfTeamA/100.0) * ((double)skillOfTeamA/100.0) * 153.0 * Math.pow((double)(100 - skillOfTeamA)/100.0, 16.0);
  //3
  a += Math.pow((double)skillOfTeamA/100.0, 3.0) * 816.0 * Math.pow((double)(100 - skillOfTeamA)/100.0, 15.0);
  //5
  a += Math.pow((double)skillOfTeamA/100.0, 5.0) * 8568.0 * Math.pow((double)(100 - skillOfTeamA)/100.0, 13.0);
  //7
  a += Math.pow((double)skillOfTeamA/100.0, 7.0) * 31824.0 * Math.pow((double)(100 - skillOfTeamA)/100.0, 11.0);
  //11
  a += Math.pow((double)skillOfTeamA/100.0, 11.0) * 31824.0 * Math.pow((double)(100 - skillOfTeamA)/100.0, 7.0);
  //13
  a += Math.pow((double)skillOfTeamA/100.0, 13.0) * 8568.0 * Math.pow((double)(100 - skillOfTeamA)/100.0, 5.0);
  //17
  a += Math.pow((double)skillOfTeamA/100.0, 17.0) * 18.0 * (double)(100 - skillOfTeamA)/100.0;
  
  //2
  b += ((double)skillOfTeamB/100.0) * ((double)skillOfTeamB/100.0) * 153.0 * Math.pow((double)(100 - skillOfTeamB)/100.0, 16.0);
  //3
  b += Math.pow((double)skillOfTeamB/100.0, 3.0) * 816.0 * Math.pow((double)(100 - skillOfTeamB)/100.0, 15.0);
  //5
  b += Math.pow((double)skillOfTeamB/100.0, 5.0) * 8568.0 * Math.pow((double)(100 - skillOfTeamB)/100.0, 13.0);
  //7
  b += Math.pow((double)skillOfTeamB/100.0, 7.0) * 31824.0 * Math.pow((double)(100 - skillOfTeamB)/100.0, 11.0);
  //11
  b += Math.pow((double)skillOfTeamB/100.0, 11.0) * 31824.0 * Math.pow((double)(100 - skillOfTeamB)/100.0, 7.0);
  //13
  b += Math.pow((double)skillOfTeamB/100.0, 13.0) * 8568.0 * Math.pow((double)(100 - skillOfTeamB)/100.0, 5.0);
  //17
  b += Math.pow((double)skillOfTeamB/100.0, 17.0) * 18.0 * (double)(100 - skillOfTeamB)/100.0;
  double c = a*b;
  return a+b-c;
 }
}
ただの計算。プログラムより電卓でやったほうがいいんじゃね?ってレベル。
確率の計算です。組み合わせはGoogle電卓で出した。
18までの素数は7つしかないので結構無理やり解いてます。

2010年11月11日木曜日

TopCoderやってみた。

知り合いに誘われてTopCoderなるものに手を出してみました。
なぜかJAVAで参戦。Python使わせてください。

とりあえず、過去問で練習してます。
だめだめですけど、自分の解答を載せます。

TopCoder SRM 430 DIV 2
Problem 500 BitwiseEquations
問題文(アカウントがないと見られません)
public class BitwiseEquations {
 public long kthPlusOrSolution(int x, int k) {
  long a = 0, shift = 0;
  while(k > 0) {
   if((x & 1) == 0) {
    a |= ((long)(k & 1) << shift);
    k >>>= 1;
   }
   x >>>= 1;
   shift++;
  }
  return a;
 }
}
xを2進数で表示したときに0になる桁に、kの2進数の1桁目から入れていく感じ。
問題文からこのことを理解できれば解ける。結構時間かかった。

TopCoder SRM 427 DIV 2
Problem 250 LoveCalculator
問題文
import java.util.Arrays;

public class LoveCalculator {
 public String findBoy(String girl, String[] boys) {
  if(boys.length == 1) return boys[0];
  
  Arrays.sort(boys);
  
  int[] love = new int[boys.length];
  for(int i = 0; i < boys.length; i++) {
   int L = 0, O = 0, V = 0, E = 0;
   for(int j = 0; j < girl.length(); j++) {
    if(girl.charAt(j) == 'L') {
     L++;
    } else if(girl.charAt(j) == 'O') {
     O++;
    } else if(girl.charAt(j) == 'V') {
     V++;
    } else if(girl.charAt(j) == 'E') {
     E++;
    }
   }
   for(int j = 0; j < boys[i].length(); j++) {
    if(boys[i].charAt(j) == 'L') {
     L++;
    } else if(boys[i].charAt(j) == 'O') {
     O++;
    } else if(boys[i].charAt(j) == 'V') {
     V++;
    } else if(boys[i].charAt(j) == 'E') {
     E++;
    }
   }
   love[i] = ((L+O)*(L+V)*(L+E)*(O+V)*(O+E)*(V+E))%100;
  }
  int max = love[0], maxI = 0;
  for(int i = 1; i < love.length; i++) {
   if(love[i] > max) {
    maxI = i;
    max = love[i];
   }
  }
  return boys[maxI];
 }
}
そのまんま。コード汚い。