做题先不要着急编代码,先找找数学规律;如果是动态规划,试着写出递推的式子
[编程题]回文序列
如果一个数字序列逆置之后跟原序列是一样的就称这样的数字序列为回文序列。例如:
{1, 2, 1}, {15, 78, 78, 15} , {112} 是回文序列,
{1, 2, 2}, {15, 78, 87, 51} ,{112, 2, 11} 不是回文序列。
现在给出一个数字序列,允许使用一种转换操作:
选择任意两个相邻的数,然后从序列移除这两个数,并用这两个数字的和插入到这两个数之前的位置(只插入一个和)。
现在对于所给序列要求出最少需要多少次操作可以将其变成回文序列。
输入描述:
输入为两行,第一行为序列长度n ( 1 ≤ n ≤ 50) 第二行为序列中的n个整数item[i] (1 ≤ iteam[i] ≤ 1000),以空格分隔。
输出描述:
输出一个数,表示最少需要的转换次数
输入
4 1 1 1 3
输出
2
数组从两边向中间加
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n=scan.nextInt();
int []arr=new int[n];
for(int i=0;i<n;i++){
arr[i]=scan.nextInt();
}
//分治递归,最终会合成一个数
int count=0,head=0,tail=n-1;
while(head<tail){
if(arr[head]<arr[tail]){
arr[head+1]+=arr[head];
head++;
count++;
}else if(arr[head]>arr[tail]){
arr[tail-1]+=arr[tail];
tail--;
count++;
}else{
head++;
tail--;
}
}
System.out.println(count);
}
}
[编程题]优雅的点
小易有一个圆心在坐标原点的圆,小易知道圆的半径的平方。小易认为在圆上的点而且横纵坐标都是整数的点是优雅的,小易现在想寻找一个算法计算出优雅的点的个数,请你来帮帮他。
例如:半径的平方如果为25
优雅的点就有:(+/-3, +/-4), (+/-4, +/-3), (0, +/-5) (+/-5, 0),一共12个点。
输入描述:
输入为一个整数,即为圆半径的平方,范围在32位int范围内。
输出描述:
输出为一个整数,即为优雅的点的个数
输入
25
输出
12
代入圆的函数求值
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int rdouble = scan.nextInt();
int count=0;
double r=Math.sqrt(rdouble);
for(int i=0;i<r;i++){
double j=Math.sqrt(rdouble-i*i);
if((int)j==j){
count++;
}
}
System.out.println(count*4);
}
}
[编程题]跳石板
小易来到了一条石板路前,每块石板上从1挨着编号为:1、2、3.......
这条石板路要根据特殊的规则才能前进:对于小易当前所在的编号为K的 石板,小易单次只能往前跳K的一个约数(不含1和K)步,即跳到K+X(X为K的一个非1和本身的约数)的位置。 小易当前处在编号为N的石板,他想跳到编号恰好为M的石板去,小易想知道最少需要跳跃几次可以到达。
例如:
N = 4,M = 24:
4->6->8->12->18->24
于是小易最少需要跳跃5次,就可以从4号石板跳到24号石板
输入描述:
输入为一行,有两个整数N,M,以空格隔开。 (4 ≤ N ≤ 100000) (N ≤ M ≤ 100000)
输出描述:
输出小易最少需要跳跃的步数,如果不能到达输出-1
输入
4 24
输出
5
动态规划!!先得出dp[i + x] = Math.min(dp[i + x], dp[i] +
1
);
在写代码,和后面买苹果的题一样
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int N=sc.nextInt();
int M=sc.nextInt();
System.out.println(leastJumpTime(N, M));
}
// 思想:动态规划
public static int leastJumpTime(int n, int m) {
if (m == n) {
return 0;
}
int steps = m - n + 1;// 算上了起点和终点
int[] dp = new int[steps];// 规划的量:到达 每个位置需要的最小步数
dp[0] = 0; // 起点
for (int i = 1; i < steps; i++) {
dp[i] = Integer.MAX_VALUE; // 初始化 表示后续位置都不能到达
}
for (int i = 0; i < steps; i++) {
if (dp[i] == Integer.MAX_VALUE) { // 该位置不能像前走
continue;
}
ArrayList<Integer> list = getAppNums(i + n); // i+n才是石板号
for (int j = 0; j < list.size(); j++) {
int x = list.get(j);
if (i + n + x <= m) {
dp[i + x] = Math.min(dp[i + x], dp[i] + 1);
}
}
}
if (dp[steps - 1] == Integer.MAX_VALUE) {
return -1;
} else {
return dp[steps - 1];
}
}
// 求因数 时间复杂度较低
public static ArrayList<Integer> getAppNums(int n) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
list.add(i);
if (n / i != i) {
list.add(n / i);
}
}
}
return list;
}
}
[编程题]暗黑的字符串
一个只包含'A'、'B'和'C'的字符串,如果存在某一段长度为3的连续子串中恰好'A'、'B'和'C'各有一个,那么这个字符串就是纯净的,否则这个字符串就是暗黑的。例如:
BAACAACCBAAA 连续子串"CBA"中包含了'A','B','C'各一个,所以是纯净的字符串
AABBCCAABB 不存在一个长度为3的连续子串包含'A','B','C',所以是暗黑的字符串
你的任务就是计算出长度为n的字符串(只包含'A'、'B'和'C'),有多少个是暗黑的字符串。
输入描述:
输入一个整数n,表示字符串长度(1 ≤ n ≤ 30)
输出描述:
输出一个整数表示有多少个暗黑字符串
输入
2 3
输出
9 21
做题之前不要先编代码,先找规律
import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int input=in.nextInt();
long []num=new long[input+1];
num[1]=3;
num[2]=9;
for(int i=3;i<=input;i++){
num[i]=2*num[i-1]+num[i-2];
}
System.out.print(num[input]);
}
}
[编程题]数字翻转
对于一个整数X,定义操作rev(X)为将X按数位翻转过来,并且去除掉前导0。例如:
如果 X = 123,则rev(X) = 321;
如果 X = 100,则rev(X) = 1.
现在给出整数x和y,要求rev(rev(x) + rev(y))为多少?
输入描述:
输入为一行,x、y(1 ≤ x、y ≤ 1000),以空格隔开。
输出描述:
输出rev(rev(x) + rev(y))的值
输入
123 100
输出
223
没什么说的
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
int X = in.nextInt();
int Y = in.nextInt();
System.out.println(rev(rev(X) + rev(Y)));
}
}
public static int rev(int a) {
int temp = a;
int newa = 0;
List<Integer> list = new ArrayList<>();
while (temp != 0) {
list.add(temp % 10);
temp = temp / 10;
}
int jinwei = 1;
for (int i = list.size() - 1; i >= 0; i--) {
newa += list.get(i) * jinwei;
jinwei *= 10;
}
return newa;
}
}
[编程题]最大的奇约数
小易是一个数论爱好者,并且对于一个数的奇数约数十分感兴趣。一天小易遇到这样一个问题: 定义函数f(x)为x最大的奇数约数,x为正整数。 例如:f(44) = 11.
现在给出一个N,需要求出 f(1) + f(2) + f(3).......f(N)
例如: N = 7
f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) = 1 + 1 + 3 + 1 + 5 + 3 + 7 = 21
小易计算这个问题遇到了困难,需要你来设计一个算法帮助他。
输入描述:
输入一个整数N (1 ≤ N ≤ 1000000000)
输出描述:
输出一个整数,即为f(1) + f(2) + f(3).......f(N)
输入
7
输出
21
//找规律:假设n=16
//while第一次:sum+=1+3+5+7+9+11+13+15(所有奇数的最大奇约数为本身),同时n减半(/2)为8
//while第二次:sum+=1+3+5+7(对应的是16,14,12,10的最大奇公约数),同时n减半为4
//while第三次:sum+=1+3(对应的是8,6的最大奇公约数),同时n减半为2
//while第四次:sum+=1(对应的是4的最大奇公约数),同时n减半为1
//while第五次:sum+=1(对应的是2的最大奇公约数),同时n减半为0
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int num=sc.nextInt();
long sum=0;
while(num!=0){
for(int i=1;i<=num;i+=2){
sum+=i;
}
num/=2;
}
System.out.println(sum);
}
}
[编程题]买苹果
小易去附近的商店买苹果,奸诈的商贩使用了捆绑交易,只提供6个每袋和8个每袋的包装(包装不可拆分)。 可是小易现在只想购买恰好n个苹果,小易想购买尽量少的袋数方便携带。如果不能购买恰好n个苹果,小易将不会购买。
输入描述:
输入一个整数n,表示小易想购买n(1 ≤ n ≤ 100)个苹果
输出描述:
输出一个整数表示最少需要购买的袋数,如果不能买恰好n个苹果则输出-1
输入
20
输出
3
同跳台阶
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int sum=in.nextInt();
int[] dp=new int [sum+1];
int []bags=new int[]{6,8};
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0]=0;
for(int i=0;i<dp.length;i++){
for(int j=0;j<bags.length;j++){
if(dp[i]==Integer.MAX_VALUE){
continue;
}
if(i+bags[j]<=sum){
dp[i+bags[j]]=Math.min(dp[i+bags[j]], dp[i]+1);
}
}
}
// for(int i=6;i<dp.length;i++){
// System.out.print(dp[i]+" ");
// }
// System.out.println();
if(dp[dp.length-1]!=Integer.MAX_VALUE){
System.out.println(dp[dp.length-1]);
}else{
System.out.println(-1);
}
}
}
[编程题]计算糖果
A,B,C三个人是好朋友,每个人手里都有一些糖果,我们不知道他们每个人手上具体有多少个糖果,但是我们知道以下的信息:
A - B, B - C, A + B, B + C. 这四个数值.每个字母代表每个人所拥有的糖果数.
现在需要通过这四个数值计算出每个人手里有多少个糖果,即A,B,C。这里保证最多只有一组整数A,B,C满足所有题设条件。
输入描述:
输入为一行,一共4个整数,分别为A - B,B - C,A + B,B + C,用空格隔开。 范围均在-30到30之间(闭区间)。
输出描述:
输出为一行,如果存在满足的整数A,B,C则按顺序输出A,B,C,用空格隔开,行末无空格。 如果不存在这样的整数A,B,C,则输出No
输入
1 -2 3 4
输出
2 1 3
没什么说的
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int Y1=in.nextInt();
int Y2=in.nextInt();
int Y3=in.nextInt();
int Y4=in.nextInt();
int A=0,B=0,C=0;
A=(Y1+Y3)/2;
B=A-Y1;
C=B-Y2;
if(B+C==Y4){
System.out.println(A+" "+B+" "+C);
}else{
System.out.println("No");
}
}
}