11/9課題講評
問題
- 問題A(Ohgas' Fortune)
-
一行に複数の数字が入力されるケースを正しく扱えれば,後は難しくない.「単利計算」の計算方法が一般常識とかなり異なっているので,問題文をよく読む必要がある.
- 問題B(Polygonal Line Search)
-
実際に回転させる方法もあるし,タートルグラフィックのように「20進んで右に曲がる」のような形式に置き換えてから一致するか調べる方法もある.
- 問題C(Numeral System)
-
数からMCXI文字列への変換は割合易しいが,逆はちょっと面倒かもしれない.文字を一文字ずつ見ていく必要がある.
結果
解答例(問題A)
// 入出力を行うので java.io.* をimport
import java.io.*;
// A.javaというファイル名で作るので,クラス名はA
class A{
// 入出力による例外(IOException)を発生する可能性があり,try文で
// 捕まえていないのでthrows IOExceptionをつける
public static void main(String args[]) throws IOException{
// 標準入力から読み込むためのBufferedReaderを作る.
BufferedReader d=new BufferedReader(new InputStreamReader(System.in));
// 一行読み込み,文字列から整数値に変換してmに入れる
int m=Integer.parseInt(d.readLine());
// m回の繰り返し.
for(int i=0;i< m;i++){
// 初期運用資金量の入力
int initial=Integer.parseInt(d.readLine());
// 運用年数の入力
int year=Integer.parseInt(d.readLine());
// 運用方法の種類数の入力
int n=Integer.parseInt(d.readLine());
// 最終資金は最低でも初期運用資金以上
int max=initial;
// 運用方法ごとに繰り返す
for(int j=0;j< n;j++){
// 入力された行を空白(" ")で区切って切り出す.
// 問題中の入力に対しては大きさ3の文字列の配列が得られる
// d.readLine().split(" ")は
// (d.readLine()).split(" ")と同じ意味
String ss[]=d.readLine().split(" ");
// 単利・複利の別を表す変数 typeを宣言,初期化
int type=Integer.parseInt(ss[0]);
// 年利率を表す変数 rateを宣言,初期化
double rate=Double.parseDouble(ss[1]);
// 毎年の手数料を表す変数 costを宣言,初期化
int cost=Integer.parseInt(ss[2]);
// 運用資金の残高Aの宣言と初期化
int A=initial;
if(type==1){ // 複利運用の場合
// year年間の繰り返し
for(int k=0;k< year;k++){
// この年の利子の計算
// 実数と整数の型変換にあるように,正の実数から整数への切り捨てはキャスト演算子(int)だけで実現できる
int B=(int)(A*rate);
// 次年度の運用資金の計算
A=A+B-cost;
}
}
else{ // 単利の運用の場合
// 利子累計Bsumの宣言と初期化
int Bsum=0;
// year年間の繰り返し
for(int k=0;k< year;k++){
// この年の利子の計算
// 実数と整数の型変換にあるように,正の実数から整数への切り捨てはキャスト演算子(int)だけで実現できる
int B=(int)(A*rate);
// 利子累計への加算
Bsum=Bsum+B;
// 次年度の運用資金の計算
A=A-cost;
}
// 最終資金の計算
A=A+Bsum;
}
// これまでの最高の最終資金maxよりもAが多かったらmaxにAを代入する
// ヒント Math.maxを使うと簡単
max=Math.max(max,A);
}
// 最高の最終資金を表示する
System.out.println(max);
}
}
}
サンプルを元に作るとだいたいこのようになると思います.
解答例(問題B)
import java.io.*;
public class B{
public static void main(String args[]) throws Exception{
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
int sax,say,rotateDegree,disx,disy,disbx,disby;
while(true){
int n = Integer.parseInt(bf.readLine());
if(n==0) break;
int bm = Integer.parseInt(bf.readLine());
int[] bx = new int[bm];
int[] by = new int[bm];
for(int i=0;i< bm;i++){
String st[] = bf.readLine().split(" ");
bx[i]=Integer.parseInt(st[0]);
by[i]=Integer.parseInt(st[1]);
}
for(int i=0;i< n;i++){
int m = Integer.parseInt(bf.readLine());
if(m!=bm){
for(int j=0;j< m;j++){
String st[] = bf.readLine().split(" ");
}
continue;
}
int[] x = new int[m];
int[] y = new int[m];
for(int j=0;j< bm;j++){
String st[] = bf.readLine().split(" ");
x[j]=Integer.parseInt(st[0]);
y[j]=Integer.parseInt(st[1]);
}
sax = bx[0]-x[0];
say = by[0]-y[0];
rotateDegree = -90;
disx = x[1] - x[0];
disy = y[1] - y[0];
disbx = bx[1] - bx[0];
disby = by[1] - by[0];
if(disbx!=0){
if(disbx==disx) rotateDegree = 0;
if(disbx==disy) rotateDegree =90;
if(disbx==(-disx)) rotateDegree = 180;
if(disbx==(-disy)) rotateDegree = 270;
}
else if(disby!=0){
if(disby==disy) rotateDegree = 0;
if(disby==(-disx)) rotateDegree =90;
if(disby==(-disy)) rotateDegree = 180;
if(disby==disx) rotateDegree = 270;
}
if(rotateDegree>=0){
for(int j=1;j< bm-1;j++){
disbx = bx[j+1] - bx[j];
disby = by[j+1] - by[j];
disx = x[j+1] - x[j];
disy = y[j+1] - y[j];
if(disbx!=0){
if(rotateDegree==90){
disby=disbx;
disbx=0;
}
if(rotateDegree==180){
disbx=-disbx;
}
if(rotateDegree==270){
disby=-disbx;
disbx=0;
}
}
else if(disby!=0){
if(rotateDegree==90){
disbx=-disby;
disby=0;
}
if(rotateDegree==180){
disby=-disby;
}
if(rotateDegree==270){
disbx=disby;
disby=0;
}
}
if(disbx!=disx) break;
if(disby!=disy) break;
if(j==bm-2) System.out.println(i+1);
}
}
sax = bx[bm-1]-x[bm-1];
say = by[bm-1]-y[bm-1];
rotateDegree = -90;
disx = x[1] - x[0];
disy = y[1] - y[0];
disbx = bx[bm-2] - bx[bm-1];
disby = by[bm-2] - by[bm-1];
if(disbx!=0){
if(disbx==disx) rotateDegree = 0;
if(disbx==disy) rotateDegree =90;
if(disbx==(-disx)) rotateDegree = 180;
if(disbx==(-disy)) rotateDegree = 270;
}
else if(disby!=0){
if(disby==disy) rotateDegree = 0;
if(disby==(-disx)) rotateDegree =90;
if(disby==(-disy)) rotateDegree = 180;
if(disby==disx) rotateDegree = 270;
}
if(rotateDegree>=0){
for(int j=1;j< bm-1;j++){
disbx = bx[bm-j-2] - bx[bm-j-1];
disby = by[bm-j-2] - by[bm-j-1];
disx = x[j+1] - x[j];
disy = y[j+1] - y[j];
if(disbx!=0){
if(rotateDegree==90){
disby=disbx;
disbx=0;
}
if(rotateDegree==180){
disbx=-disbx;
}
if(rotateDegree==270){
disby=-disbx;
disbx=0;
}
}
else if(disby!=0){
if(rotateDegree==90){
disbx=-disby;
disby=0;
}
if(rotateDegree==180){
disby=-disby;
}
if(rotateDegree==270){
disbx=disby;
disby=0;
}
}
if(disbx!=disx) break;
if(disby!=disy) break;
if(j==bm-2) System.out.println(i+1);
}
}
}
System.out.println("+++++");
}
}
}
import java.io.*;
class B{
static boolean eq(int x[],int y[],int anox[],int anoy[],int N){
int[] di=new int[2];
if(x.length!=anox.length)return false;
di[0]=1;di[1]=-1;
if((Math.pow(x[0]-x[1],2)+Math.pow(y[0]-y[1],2))!=(Math.pow(anox[0]-anox[1],2)+Math.pow(anoy[0]-anoy[1],2)))return false;
for(int k=1;k< N-1;k++){
if((Math.pow(x[k]-x[k+1],2)+Math.pow(y[k]-y[k+1],2))!=(Math.pow(anox[k]-anox[k+1],2)+Math.pow(anoy[k]-anoy[k+1],2)))return false;
if(x[k-1]==x[k] && y[k-1] < y[k]){
if(x[k]< x[k+1]){di[0]=1;}else{di[0]=-1;}
}else if(x[k-1]==x[k] && y[k-1] > y[k]){
if(x[k]< x[k+1]){di[0]=-1;}else{di[0]=1;}
}else if(y[k-1]==y[k] && x[k-1] < x[k]){
if(y[k]< y[k+1]){di[0]=-1;}else{di[0]=1;}
}else if(y[k-1]==y[k] && x[k-1] > x[k]){
if(y[k]< y[k+1]){di[0]=1;}else{di[0]=-1;}
}
if(anox[k-1]==anox[k] && anoy[k-1] < anoy[k]){
if(anox[k]< anox[k+1]){di[1]=1;}else{di[1]=-1;}
}else if(anox[k-1]==anox[k] && anoy[k-1] > anoy[k]){
if(anox[k]< anox[k+1]){di[1]=-1;}else{di[1]=1;}
}else if(anoy[k-1]==anoy[k] && anox[k-1] < anox[k]){
if(anoy[k]< anoy[k+1]){di[1]=-1;}else{di[1]=1;}
}else if(anoy[k-1]==anoy[k] && anox[k-1] > anox[k]){
if(anoy[k]< anoy[k+1]){di[1]=1;}else{di[1]=-1;}
}
if(di[0]!=di[1])return false;
}
return true;
}
static boolean eq2(int x[],int y[],int anox[],int anoy[],int n){
int N=n-1;
int[] di=new int[2];
if(x.length!=anox.length)return false;
di[0]=1;di[1]=-1;
if((Math.pow(x[0]-x[1],2)+Math.pow(y[0]-y[1],2))!=(Math.pow(anox[N]-anox[N-1],2)+Math.pow(anoy[N]-anoy[N-1],2)))return false;
for(int k=1;k< N-1;k++){
if((Math.pow(x[k]-x[k+1],2)+Math.pow(y[k]-y[k+1],2))!=(Math.pow(anox[N-k]-anox[N-k-1],2)+Math.pow(anoy[N-k]-anoy[N-k-1],2)))return false;
if(x[k-1]==x[k] && y[k-1] < y[k]){
if(x[k]< x[k+1]){di[0]=1;}else{di[0]=-1;}
}else if(x[k-1]==x[k] && y[k-1] > y[k]){
if(x[k]< x[k+1]){di[0]=-1;}else{di[0]=1;}
}else if(y[k-1]==y[k] && x[k-1] < x[k]){
if(y[k]< y[k+1]){di[0]=-1;}else{di[0]=1;}
}else if(y[k-1]==y[k] && x[k-1] > x[k]){
if(y[k]< y[k+1]){di[0]=1;}else{di[0]=-1;}
}
if(anox[N-k+1]==anox[N-k] && anoy[N-k+1] < anoy[N-k]){
if(anox[N-k]< anox[N-k-1]){di[1]=1;}else{di[1]=-1;}
}else if(anox[N-k+1]==anox[N-k] && anoy[N-k+1] > anoy[N-k]){
if(anox[N-k]< anox[N-k-1]){di[1]=-1;}else{di[1]=1;}
}else if(anoy[N-k+1]==anoy[N-k] && anox[N-k+1] < anox[N-k]){
if(anoy[N-k]< anoy[N-k-1]){di[1]=-1;}else{di[1]=1;}
}else if(anoy[N-k+1]==anoy[N-k] && anox[N-k+1] > anox[N-k]){
if(anoy[N-k]< anoy[N-k-1]){di[1]=1;}else{di[1]=-1;}
}
if(di[0]!=di[1])return false;
}
return true;
}
public static void main(String args[]) throws IOException{
BufferedReader d=new BufferedReader(new InputStreamReader(System.in));
int count=0;
boolean flag[]=new boolean[2];
while(true){
int num=Integer.parseInt(d.readLine());
if(num==0)break;
int num2=Integer.parseInt(d.readLine());
int[] orgx=new int[num2];
int[] orgy=new int[num2];
for(int i=0;i< num2;i++){
String[] str=d.readLine().split(" ");
orgx[i]=Integer.parseInt(str[0]);
orgy[i]=Integer.parseInt(str[1]);
}
for(int j=0;j< num;j++){
num2=Integer.parseInt(d.readLine());
int[] copx=new int[num2];
int[] copy=new int[num2];
for(int i=0;i< num2;i++){
String[] str=d.readLine().split(" ");
copx[i]=Integer.parseInt(str[0]);
copy[i]=Integer.parseInt(str[1]);
}
if(eq(orgx,orgy,copx,copy,num2)==true){
System.out.println(j+1);
}
if(eq2(orgx,orgy,copx,copy,num2)==true){
System.out.println(j+1);
}
}
System.out.println("+++++");
}
}
}
4方向を別々にコーディングするところなど,力強い(悪くいうと力まかせ)なところが,あります.こちらの用意した問題Bのサンプルプログラムは以下のようなものです.
import java.io.*;
class Point{
int x,y;
Point(int xx,int yy){
x=xx; y=yy;
}
boolean equals(Point p){
return p.x==x && p.y==y;
}
Point diff(Point p2){
return new Point(x-p2.x,y-p2.y);
}
Point rot(int i){
switch(i){
case 0: return new Point(x,y);
case 1: return new Point(-y,x);
case 2: return new Point(-x,-y);
case 3: return new Point(y,-x);
}
return new Point(0,0);
}
static Point[] read(BufferedReader d) throws IOException{
int m=Integer.parseInt(d.readLine());
Point[] ret=new Point[m];
for(int i=0;i< m;i++){
String[] ss=d.readLine().split(" ");
ret[i]=new Point(Integer.parseInt(ss[0]),
Integer.parseInt(ss[1]));
}
return ret;
}
static Point[] reverse(Point[] ps){
Point[] ret=new Point[ps.length];
for(int i=0;i< ps.length;i++){
ret[i]=ps[ps.length-i-1];
}
return ret;
}
static boolean isSameRot(Point[] ps1,Point[] ps2,int rot){
for(int i=0;i< ps1.length-1;i++){
Point d1=ps1[i+1].diff(ps1[i]);
Point d2=ps2[i+1].diff(ps2[i]).rot(rot);
if(!d1.equals(d2)) return false;
}
return true;
}
static boolean isSame(Point[] ps1,Point[] ps2){
if(ps1.length!=ps2.length) return false;
for(int i=0;i<4;i++)
if(isSameRot(ps1,ps2,i)) return true;
return false;
}
}
class B{
public static void main(String[] args) throws IOException{
BufferedReader d=new BufferedReader(new InputStreamReader(System.in));
for(;;){
int n=Integer.parseInt(d.readLine());
if(n==0)break;
Point[] sample=Point.read(d);
Point[] revSample=Point.reverse(sample);
for(int i=1;i<=n;i++){
Point[] dest=Point.read(d);
if( Point.isSame(sample,dest) ||
Point.isSame(revSample,dest)){
System.out.println(i);
}
}
System.out.println("+++++");
}
}
}
解答例(問題C)
import java.io.*;
class C{
static char[] mcxi={'i','x','c','m'};
static char[] digit={'0','1','2','3','4','5','6','7','8','9'};
public static void main(String[] args) throws IOException{
BufferedReader r=new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(r.readLine());
for (int i=0;i< n;i++){
String mcxi[]=r.readLine().split(" ");
System.out.println(int2mcxi(mcxi2int(mcxi[0])+mcxi2int(mcxi[1])));
}
}
static int mcxi2int(String input){
int result=0;
int base=0;
for(int i=input.length()-1;i>=0;i--){
int num=input.charAt(i);
switch(num){
case 'i':
base=1;
result+=base;
break;
case 'x':
base=10;
result+=base;
break;
case 'c':
base=100;
result+=base;
break;
case 'm':
base=1000;
result+=base;
break;
//変な入力がきてもエラーにならないように
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
result-=base;
result+=base*Character.digit((char)num, 10);
}
}
return result;
}
//正数だけだけど
static String int2mcxi(int input){
StringBuffer mcxistr=new StringBuffer();
int temp=input;
for(int i=0;i<4;i++){
int num=temp%10;
switch(num){
case 0:
break;
case 1:
mcxistr.insert(0,mcxi[i]);
break;
default:
mcxistr.insert(0,mcxi[i]);
mcxistr.insert(0,digit[num]);
break;
}
temp/=10;
}
return mcxistr.toString();
}
}
奇麗に書いていますね.int2mcxiでStringを作る際に,StringBufferにinsertしていくなど効率も考えて書かれています.