蓝桥杯练习——基础训练
题目练习
字母图形
【问题描述】
利用字母可以组成一些美丽的图形,下面给出了一个例子:
ABCDEFG
BABCDEF
CBABCDE
DCBABCD
EDCBABC
这是一个5行7列的图形,请找出这个图形的规律,并输出一个n行m列的图形。
【输入格式】
输入一行,包含两个整数n和m,分别表示你要输出的图形的行数的列数。
【输出格式】
输出n行,每个m个字符,为你的图形。
【样例输入】
5 7
【样例输出】
ABCDEFG
BABCDEF
CBABCDE
DCBABCD
EDCBABC
【数据规模与约定】
1 <= n, m <= 26。
思路
整体就是,每行以A为基准,然后向两边一边增大一边填数,思路很简单,但是实操。。
咋说呢,一开始写了个运行错误的代码,有三组比较奇葩的数据没过。因为我一开始的思路是先把每行行号列号相等的地方把A填完了然后再填别的,结果有的数据列号比行号小,这个方法就不行了
(错误版本)
import java.util.Scanner;
public class ZimuPicWA {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner=new Scanner(System.in);
int n,m,i,j,k;
char c='B';
n=scanner.nextInt();
m=scanner.nextInt();
char ch[][]=new char[n+1][m+1];
for(i=1;i<=n;i++) {
ch[i][i]='A';
for(j=i+1;j<=m;j++) {
ch[i][j]=c;
c++;
}
c='B';
for(k=i-1;k>=1;k--) {
ch[i][k]=c;
c++;
}
c='B';
}
for(i=1;i<=n;i++) {
for(j=1;j<=m;j++) {
System.out.print(ch[i][j]);
}
System.out.println();
}
}
}
于是改变一下思路,不要先把A填完,而是随着循环每遇到一个数就去判断,这样就不会出现数组超界的情况。
对于j大于i的部分横向比较并填数,j小于i的部分竖向比较并填数。
代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
int m=scanner.nextInt();
char ch[][]=new char[n+1][m+1];
int i,j;
for(i=1;i<=n;i++) {
for(j=1;j<=m;j++) {
if(i==j) {
ch[i][j]='A';
}
else if(i>j) {
ch[i][j]=(char) (ch[i-1][j]+1);
}
else {
ch[i][j]=(char) (ch[i][j-1]+1);
}
}
}
for(i=1;i<=n;i++) {
for(j=1;j<=m;j++) {
System.out.print(ch[i][j]);
}
System.out.println();
}
}
}
视频学习
数的划分
【问题描述】
对于整数6,可以将其进行划分,形式如下所示:
6
5+1
4+2,4+1+1
3+3,3+2+1,3+1+1+1
2+2+2,2+2+1+1,2+1+1+1+1
1+1+1+1+1+1
现在,对于给定的正整数n,变成打印所有划分
【输入 】n
【输出】所有划分的可能
思路
这个问题可以用递归的思想解决。比如对于每行从n到1,先确定一个加数,然后剩下的问题重复这一模式,不断往下寻找符合的数
situ数组:是一个用来记录的数组,记录对于每一组分解,每次分解出的数据
fun函数:用来递归找出符合条件的组合,其中k代表当前循环到的位置
因为输出形式中某一次的拆分样式都是前面的数大于后面的数,所以加一条 if(k>0&&i>situ[k-1])continue; 语句表示如果此时进行到的位置k前有数并且正在尝试填入的数i大于它前面的数,则这次作废
代码
import java.util.Scanner;
public class ShuHuaFen {
public static void fun(int n,int []situ,int k) { //k是当前递归进行到哪个位置了
int i;
if(n<=0) { //输出每种可能
for(i=0;i<k;i++) {
if(i!=k-1)System.out.print(situ[i]+"+");
else {
System.out.print(situ[i]);
}
}
System.out.println();
return;
}
for(i=n;i>0;i--) {
if(k>0&&i>situ[k-1])continue; //k>0表示前面还有数
situ[k]=i; //一种拆分可能的一个数进入situ数组
fun(n-i, situ, k+1); //n-i表示下层递归从剪掉这个数剩下的部分开始
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
int []situ=new int[1000]; //缓冲数组,存放分解出的数字
fun(n,situ,0);
}
}