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していくなど効率も考えて書かれています.