湘潭大学OJ-2019年期末考试题目JAVA版

如果觉得内容对你有帮助,不妨点赞一波!

题目顺序

  • 小鸡跳呀跳
    • 题目描述
    • 输入
    • 输出
    • 样例输入
    • 样例输出
    • 代码
  • X
    • 题目描述
    • 输入
    • 输出
    • 样例输入
    • 样例输出
    • 代码
  • Circle
    • 题目描述
    • 输入
    • 输出
    • 样例输入
    • 样例输出
    • 代码
  • 连分数
    • 题目描述
    • 输入
    • 输出
    • 样例输入
    • 样例输出
    • 代码
  • Fibonacci
    • 题目描述
    • 输入
    • 输出
    • 样例输入
    • 样例输出
    • 代码
  • 回文数
    • 题目描述
    • 输入
    • 输出
    • 样例输入
    • 样例输出
    • 代码
  • Factorization
    • 题目描述
    • 输入
    • 输出
    • 样例输入
    • 样例输出
    • 代码
  • Blocks
    • 题目描述
    • 输入
    • 输出
    • 样例输入
    • 样例输出
    • 代码

小鸡跳呀跳

题目描述

小鸡跳呀跳是eric喜欢的一个小游戏,画面上会不断出现各种障碍物和金币,eric可以控制小鸡不断跳来跳去,通过障碍物,获取金币。如果不小心碰到障碍物,游戏就结束了。游戏的积分规则如下:

游戏开始积分为0。
获取一个金币,得分20。
连续获得金币,第1个多得10,第2个多得20,第3个或以上多得30分。
总积分是所有分数的累加
请写一个程序来帮eric计算一下每次游戏的得分。

输入

第一行是一个整数T(1≤T≤1000),表示样例的个数。 以后每行一个样例,为一个不长度不超过200个字符的字符串,字符串中只存在OX#三种字符,O表示通过障碍物并获得一个金币,X表示通过障碍物,#表示碰到障碍物。

输出

每行输出一个样例的结果,为一个整数。

样例输入

2
OOO#
XXX#

样例输出

90
0

代码

import java.util.Scanner;

public class P1371 {
    public static void main(String args[]){
        Scanner s = new Scanner(System.in);
        int T = s.nextInt();
        while ((T--)>0){
            String ob = s.next();
            int score = 0;
            int cross = 0;
            for(int i=0;i<ob.length();i++){
                char c = ob.charAt(i);
                if(c=='O'){
                    int get = 20+cross*10;
                    score+=get;
                    if(cross<3)
                        cross++;
                }else if(c=='#'){
                    break;
                }else if(c=='X'){
                    cross=0;
                }
            }
            System.out.println(score);
        }
    }
}

X

题目描述

输出一个"X"型字符图形,给定字符为c,格式要求

图形的中心是字符’X’
四个斜轴上依次是字符’A’到给定c
行尾无空格。
具体见样例。

输入

每行一个字符c,字符只含大写字母。

输出

按顺序输出每个样例的对应结果。

样例输入

A
C

样例输出

A A
 X
A A
C     C
 B   B
  A A
   X
  A A
 B   B
C     C

提示
注意输入中回车也是字符!

代码

import java.util.Scanner;

public class P1372 {
    public static void main(String args[]){
        Scanner s = new Scanner(System.in);
        while (true){
            String ch = s.next();
            char c = ch.charAt(0);
            int len = c-'A'+1;
            int bounds = 2*len;
            //four steps
            for(int i=0;i<=bounds;i++){
                for(int j=0;j<=bounds;j++){
                    if(i==j&&i!=len){
                        if(i<len){
                            System.out.print((char) (c-i));
                        }else{
                            System.out.print((char) ('A'+i-len-1));
                        }
                    } else if(i+j==bounds&&i!=len&&j!=len){
                        if(i<len){
                            System.out.print((char) (c-i));
                        }else{
                            System.out.print((char) ('A'+i-len-1));
                        }
                    }else {
                        if(i==len&&j==len){
                            System.out.print("X");
                        }else{
                            System.out.print(" ");
                        }
                    }
                }
                System.out.println("");
            }
        }
    }
}

Circle

题目描述

给你两个圆的圆心坐标和半径,请判断一下两个圆是下列哪种情况:

包含:一个圆在另外一个圆内,两圆无交点
内切:一个圆在另外一个圆内,一个交点
相交:两个圆交于两点
外切:两个圆交于1点,且圆没有嵌套
相离:圆没有嵌套且没有交点

输入

第一行是一个整数T(1≤T≤1000),表示样例的个数。

每个样例是两行,每行三个整数,x,y,r(1≤x,y,r≤1000),分别表示一个圆的圆心坐标和半径

输出

依次每行输出一个样例的结果,如果包含输出1,内切输出2,相交输出3,,外切输出4,想离输出5。

样例输入

5
0 0 2
0 0 1
0 0 2
1 0 1
0 0 2
1 0 2
0 0 2
3 0 1
0 0 2
4 0 1  

样例输出

1
2
3
4
5

代码

import java.util.Scanner;

public class P1373 {
    public static void main(String args[]){
        Scanner s = new Scanner(System.in);
        int T = s.nextInt();
        while ((T--)>0){
            int cir1[] = new int[4];
            int cir2[] = new int[4];
            for(int i=0;i<3;i++)
                cir1[i]=s.nextInt();
            for(int i=0;i<3;i++)
                cir2[i]=s.nextInt();
            double dis = (cir1[0]-cir2[0])*(cir1[0]-cir2[0])+(cir1[1]-cir2[1])*(cir1[1]-cir2[1]);//(x1-x2)^2 + (y1-y2)^2
            dis = Math.sqrt(dis);
            int centerSur = Math.abs(cir1[2]-cir2[2]);// center of circle distance
            int centerPlus = cir2[2]+cir1[2];
            if(centerSur>dis){
                System.out.println(1);
            }else if(centerSur==dis){
                System.out.println(2);
            }else if(centerPlus>dis){
                System.out.println(3);
            }else if(centerPlus==dis){
                System.out.println(4);
            }else if(centerPlus<dis){
                System.out.println(5);
            }
        }
    }
}

连分数

题目描述

x=b1a1+b2a2+b3a3+⋯
比如 n=3,a1=1,a2=2,a3=3,b1=3,b2=2,b3=1时
x=31+22+13=2113

给定n,ai,i=1,2,…,n,请求x,并按最简方式表示x。(具体题目描述见这里)

输入

第一个行是一个整数T(1≤T≤100),表示样例的个数。 以后每个样例的第一行为整数n(1≤n≤9); 第二行为n个整数,为ai,(1≤ai≤100); 第三行为n个整数,为bi,(1≤bi≤100)。

输出

按顺序输出一个样例的结果,如果结果为整数,输出整数;如果结果为分数,格式为"分子/分母",保证分子与分母互质。

样例输入

3
3 
1 2 3
3 2 1
3
1 2 3
4 7 1
9
100 100 100 100 100 100 100 100 100
99 99 99 99 99 99 99 99 99

样例输出

21/13
1
1060072063970000499/1081277664009800500

代码

import java.util.Scanner;
public class Main {
    public static void main(String args[]){
        Scanner s = new Scanner(System.in);
        int T = s.nextInt();
        long up,down;
        while (T>0){
            T=T-1;
            int i;
            int n = s.nextInt();
            long a[] = new long[n];
            long b[] = new long[n];
            for(i=0;i<n;i++){
                a[i] = s.nextLong();
            }
            for(i=0;i<n;i++){
                b[i]=s.nextLong();
            }
            for(i=n-1;i>=1;i--){
                up = a[i]*a[i-1]+b[i];
                down = a[i];
                b[i-1]=b[i-1]*down;
                a[i-1]=up;
            }
            if(b[0]%a[0]==0){
                System.out.println((b[0]/a[0]));
            } else{
                long value = getMaxYue(a[0],b[0]);
                System.out.println((b[0]/value)+"/"+(a[0]/value));
            }
        }
    }
    public static long getMaxYue(long a,long b){
        while(a%b!=0){
            long res = a % b;
            if(res==0){
                return b;
            }
            a = b;
            b = res;
        }
        return b;
    }
}

Fibonacci

题目描述

小明非常喜欢Fibonacci数列,数列为 f1=1,f2=2,fn=fn−1+fn−2。 小明想知道对于一个整数n,使得n=fi+fj+fk的组合有多少种? 比如5=1+1+3 或者 5=1+2+2,有2种。注意 1+2+2 和 2+1+2 被认为是同一种。

输入

第一行是一个整数T(1≤T≤1000),表示样例的个数。

每个样例是一个整数n(3≤n≤109)。

输出

依次每行输出一个样例的结果,为一个整数。

样例输入

2
3
5

样例输出

1
2

代码

import java.util.*;

public class P1375 {
    private static long counts = 0;
    public static void main(String args[]){
        Scanner s = new Scanner(System.in);
        int T = s.nextInt();
        while (T>0){
            counts=0;
            T = T - 1;
            long n = s.nextInt();
            long f[] = new long[46];
            f[0]=1;
            f[1]=2;
            for(int i=2;i<46;i++){
                f[i] = f[i-1]+f[i-2];
            }
            List<Long> mid = new ArrayList<>();
            dfs(n,f,0,n,0);
            System.out.println(counts);
        }
    }

    public static void dfs(long res,long f[],int len,long tar,int pos){
        if(res==0){
            if(len==3){
                counts++;
            }
            return;
        }
        if(res<0 || len>3 || res > tar){
            return;
        }

        for(int i = pos;i<46;i++){
            if(f[i]>tar){
                return;
            }
            dfs(res-f[i],f,len+1,tar,i);
        }
    }
}

回文数

题目描述

回文数是指一个没有前导0的数,从左到右的数码和从右到左的数码是一样的。比如说10进制下的"121",这就是一个回文数。

我们将这个概念扩展到b进制,n=∑ki=0ai⋅bi,其中0≤ai0,如果数列ak,ak−1,…,a0构成一个回文序列,那么就称n在b进制下是回文数。比如,5在2进制下是101(2),所以5在2进制下是回文数。

我们想知道n在b进制下为回文数时,最小的b是多少?

输入

第一行是一个整数T(1≤T≤1000),表示样例的个数。

每个样例是一个十进制整数n(1≤n≤106)。

输出

依次每行输出一个样例的结果,为一个整数,表示b。

样例输入

2 
5 
6

样例输出

2 
5

代码

import java.util.Scanner;

public class P1376 {
    public static void main(String args[]){
        Scanner s = new Scanner(System.in);
        int T = s.nextInt();
        while (T>0){
            T=T-1;
            int n = s.nextInt();
            for(int i=2;;i++){
                int nums[] = new int[20];//max num is 100000
                int count = 0;//calculate the bit num
                int mid = n;
                while (mid!=0){
                    nums[count++] = mid%i;
                    mid/=i;
                    if(mid==0){
                        break;
                    }
                }
                boolean flag = judgeHuiWen(nums,count);
                if(flag){
                    System.out.println(i);
                    break;
                }
            }
        }
    }

    /**
     * judge whether it is a huiwen number
     * @param nums
     * @param count
     * @return
     */
    public static boolean judgeHuiWen(int nums[],int count){
        int bounds = (count/2)-1;
        for(int i = 0;i<=bounds;i++){
            if(nums[i]!=nums[count-i-1]){
                return false;
            }
        }
        return true;
    }
}

Factorization

题目描述

根据质因子唯一分解定理可知n=pk11pk22…pkmm,其中pi都是质数。我们定义f(n)=m, 求g(a,b)=∑bi=af(n)。

输入

第一行是一个整数T(1≤T≤1000),表示样例的个数。
以后每个样例占一行,为两个整数 a(2≤a≤b≤106)。

输出

依次每行输出一个样例的结果,为一个整数。

样例输入

2
2 2
2 10

样例输出

1
11

代码

#include
#define MAX 1000000
int form[MAX]={0};//记录素数
int prime[MAX];
int fn[MAX];
int counts = 0;
void recordPrime(){
    //打表记录素数,为0表示是素数 
    int i,j;
    for(i=2;i<=MAX/2;i++){
        for(j=2*i;j<=MAX;j+=i){
            form[j]=1;
        }
    }
    
    for(int i=2;i<=MAX;i++){
        if(!form[i]){
            prime[counts++]=i;
        }
    }
} 

void recordFn(){
    int i,j;
    for(i=2;i<=MAX;i++){
        int mid = i;
        int res = 0;
        for(j=0;j<counts&&prime[j]*prime[j]<=i;j++){
            if(mid%prime[j]==0){
                res++;
                while(mid%prime[j]==0){
                    mid/=prime[j];
                }
            }
        }
        if(mid!=1){
            res++;
        }
        fn[i]=res;
    }
    
    for(int i=3;i<=MAX;i++){
        fn[i]+=fn[i-1];
    }
}
int main(){
    int T;
    recordPrime();
    
    //然后保存1-1000000每一个数fn的值
    recordFn();
    scanf("%d",&T);
    while(T--){
        int a,b;
        scanf("%d %d",&a,&b);
        printf("%d\n",fn[b]-fn[a-1]);
    } 
} 

Blocks

题目描述

给你一个n块积木,每个积木块都是立方体,现在把它们排列一排,成m列,要求每列上至少有1个积木,且从左到右,每列的积木数量呈严格单调下降。比如8块积木,排成3列,那么合法的安排方案为521或者431。请问n块积木按规则排成m有多少种不同的方案?

输入

第一行是一个整数T(1≤T≤1000),表示样例的个数。

以后每个样例占一行,为两个整数 n(1≤n≤100),m(1≤m≤10)。

输出

依次每行输出一个样例的结果,为一个整数。

样例输入

2
8 3
13 4

样例输出

2
3

样例解释
第二个样例的合法方案为7321,6421,5431

代码

import java.util.Scanner;

public class P1378 {
    public static void main(String args[]){
        Scanner s = new Scanner(System.in);
        int T = s.nextInt();
        while (T>0){
            T--;
            int counts = 0;
            int n = s.nextInt();
            int m = s.nextInt();
            //dynamic program
            int[][][] dp = new int[n+1][m+1][n+1];
            dp[1][1][1]=1;//init the situation that there is only one
            for(int i=2;i<=n;i++){
                for(int j=1;j<=m;j++){
                    for(int k=1;k<=i;k++){
                        if(j==1&&i==k){
                            dp[i][j][k]=1;//only one column
                        }else {
                            for(int a = k-1;a >= 1;a--){
                                dp[i][j][k]+=dp[i-k][j-1][a];
                            }
                        }
                    }
                }
            }
            for(int i=1;i<=n;i++){
                counts+=dp[n][m][i];
            }
            System.out.println(counts);
        }
    }
}

你可能感兴趣的:(题解,动态规划,贪心算法,dfs)