kanetaiの二次記憶装置

プログラミングに関するやってみた、調べた系のものをQitaに移して、それ以外をはてブでやる運用にしようと思います。http://qiita.com/kanetai

[OnlineJuCutting Down Water Bills(AOJ No.0216), Walking in the Hospital(AOJ No.0217), Dividing Students(AOJ No.0218), A Popular Ice-cream Shop(AOJ No.0219), Binary Digit A Doctor Loved(AOJ No.0220)

リポジトリ

Cutting Down Water Bills(AOJ No.0216)

段階 水量 料金
第 1 段階料金 10  m^3まで 基本料金 1150 円
第 2 段階料金 10  m^3超過 20  m^3まで 1  m^3あたり 125 円
第 3 段階料金 20  m^3超過 30  m^3まで 1  m^3あたり 140 円
第 4 段階料金 30  m^3超過分 1  m^3あたり 160 円

今月の使用水量 w m^3が与えられて、上記の通りに水道料金を計算したときの水道料金と先月の料金(4280 円)との差額を求める。
制約
 1 \leq w \leq 100

コード

import java.util.*;
public class aoj0216 {
	static final Scanner stdin = new Scanner(System.in);
	public static void main(String[] args) {
		while (true) {
			int n = stdin.nextInt(), a = 4280 - 1150, temp;
			if (n == -1) break;
			if (n >= 30) { temp = n - 30;  a -= (160 * temp);  n -= temp; } 
			if (n >= 20) { temp = n - 20;  a -= (140 * temp);  n -= temp; } 
			if (n >= 10) { temp = n - 10;  a -= (125 * temp);  n -= temp; }
			System.out.println(a);
		}
	}
}

Walking in the Hospital(AOJ No.0217)

{p, d1, d2}というレコードがn個与えられて、その中で、d1+d2が最大になるpを求める。
制約
 0 < n, p \leq 10000
 0\leq d1, d2 \leq 5000

コード

import java.util.*;
public class aoj0217 {
	static final Scanner stdin = new Scanner(System.in);
	public static void main(String[] args) {
		while (true) {
			int n = stdin.nextInt(), id = -1, d = -1;
			if (n == 0) break;
			while (n-- > 0) {
				int tmpid = stdin.nextInt(), tmpd = stdin.nextInt() + stdin.nextInt();
				if (d < tmpd) { id = tmpid; d = tmpd; }
			}
			System.out.println(id + " " + d);
		}
	}
}

Dividing Students(AOJ No.0218)

条件 クラス
100 点の科目がある A
数学と英語の平均点が 90 点以上 A
3 科目の平均点が 80 点以上 A
3 科目の平均点が 70 点以上 B
3 科目の平均点が 50 点以上で数学か英語が 80 点以上 B
上の条件を満たさない C

生徒の人数 n、各生徒の数学の点数 pm、英語の点数 pe、国語の点数 pj を入力とし、上記の表に従って、各生徒のクラスA,B,Cを求める。
制約
 0 < n \leq 10,000
 0\leq pm, pe, pj \leq 100

コード

import java.util.*;
public class aoj0218 {
	static final Scanner stdin = new Scanner(System.in);
	public static void main(String[] args) {
		while (true) {
			int n = stdin.nextInt();
			if (n == 0) break;
			while (n-- > 0) {
				int m = stdin.nextInt(), e = stdin.nextInt(), j = stdin.nextInt(), ave = (m + e + j) / 3;
				System.out.println(((m == 100 || e == 100 || j == 100) || ((m + e) / 2 >= 90) || ave >= 80) ? "A" :
					(ave >= 70 || (ave >= 50 && (m >= 80 || e >= 80))) ? "B" : "C");
			}
		}
	}
}

A Popular Ice-cream Shop(AOJ No.0219)

0-9のIDの系列がn個入力されるので、その数を数えてヒストグラムを作る
制約
 1 < n \leq 10,000

コード

import java.util.*;
public class aoj0219 {
	static final Scanner stdin = new Scanner(System.in);
	static final int N = 10;
	public static void main(String[] args) {
		while (true) {
			int n = stdin.nextInt();
			if (n == 0) break;
			int[] p = new int[N];
			while (n-- > 0) p[stdin.nextInt()]++;
			for (int x : p) {
				if (x == 0) System.out.print("-");
				else while (x-- > 0) System.out.print("*");
				System.out.println();
			}
		}
	}
}

Binary Digit A Doctor Loved(AOJ No.0220)

正の実数が与えられて、それを2進数表示する。整数部8桁以内+小数部4桁以内に収まらない場合はNAと答える。

アルゴリズム

整数部の桁制約を満たしているかどうかは、小数部を切り捨てたものをbinary表示に直し、それが8桁に収まっているかどうかで判断する。
小数部の桁制約を満たしているかどうかは、4bit左シフト( 2^4倍)してそれが整数になっているか(小数部が0かどうか)で判断すれば良い。
javaだと2進数表示は、toBinaryString()で簡単にできる。
ビットシフトして、桁数まで0をパディングした後に、整数部8桁と小数部4桁に分割して、間に小数点を入れる。

コード

import java.util.*;
public class aoj0220 {
	static final Scanner stdin = new Scanner(System.in);
	static final int INT = 8, FRAC = 4;
	static final String binary(int i, int num) {
		StringBuilder sb = new StringBuilder(Integer.toBinaryString(i)).reverse();
		while (sb.length() < num) sb.append("0");
		return sb.reverse().toString();
	}
	public static void main(String[] args) {
		while (true) {
			double x = Double.parseDouble(stdin.next());
			if (x < 0) break;
			String[] xx = ((x*(1<<FRAC)) + "").split("\\.");
			String str = binary(Integer.parseInt(xx[0]), FRAC+INT);
			System.out.println(
					(xx.length == 2 && Integer.parseInt(xx[1]) != 0) || Integer.toBinaryString((int)x).length() > INT ? 
					"NA" : str.substring(0, INT) + "." + str.substring(INT));
		}
	}
}