8.第十届蓝桥杯 国赛 java C组
https://blog.csdn.net/qq_43449564/article/details/109399852
https://blog.csdn.net/our1624204500/article/details/109537349
https://blog.csdn.net/qq_43652327/article/details/109583675
https://blog.csdn.net/weixin_48598155/article/details/109364649
B递增序列
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class 递增序列2 {
public static void main(String[] args) throws IOException {
String ssString =
"VLPWJVVNNZSWFGHSFRBCOIJTPYNEURPIGKQGPSXUGNELGRVZAG\r\n" +
"SDLLOVGRTWEYZKKXNKIRWGZWXWRHKXFASATDWZAPZRNHTNNGQF\r\n" +
"ZGUGXVQDQAEAHOQEADMWWXFBXECKAVIGPTKTTQFWSWPKRPSMGA\r\n" +
"BDGMGYHAOPPRRHKYZCMFZEDELCALTBSWNTAODXYVHQNDASUFRL\r\n" +
"YVYWQZUTEPFSFXLTZBMBQETXGXFUEBHGMJKBPNIHMYOELYZIKH\r\n" +
"ZYZHSLTCGNANNXTUJGBYKUOJMGOGRDPKEUGVHNZJZHDUNRERBU\r\n" +
"XFPTZKTPVQPJEMBHNTUBSMIYEGXNWQSBZMHMDRZZMJPZQTCWLR\r\n" +
"ZNXOKBITTPSHEXWHZXFLWEMPZTBVNKNYSHCIQRIKQHFRAYWOPG\r\n" +
"MHJKFYYBQSDPOVJICWWGGCOZSBGLSOXOFDAADZYEOBKDDTMQPA\r\n" +
"VIDPIGELBYMEVQLASLQRUKMXSEWGHRSFVXOMHSJWWXHIBCGVIF\r\n" +
"GWRFRFLHAMYWYZOIQODBIHHRIIMWJWJGYPFAHZZWJKRGOISUJC\r\n" +
"EKQKKPNEYCBWOQHTYFHHQZRLFNDOVXTWASSQWXKBIVTKTUIASK\r\n" +
"PEKNJFIVBKOZUEPPHIWLUBFUDWPIDRJKAZVJKPBRHCRMGNMFWW\r\n" +
"CGZAXHXPDELTACGUWBXWNNZNDQYYCIQRJCULIEBQBLLMJEUSZP\r\n" +
"RWHHQMBIJWTQPUFNAESPZHAQARNIDUCRYQAZMNVRVZUJOZUDGS\r\n" +
"PFGAYBDEECHUXFUZIKAXYDFWJNSAOPJYWUIEJSCORRBVQHCHMR\r\n" +
"JNVIPVEMQSHCCAXMWEFSYIGFPIXNIDXOTXTNBCHSHUZGKXFECL\r\n" +
"YZBAIIOTWLREPZISBGJLQDALKZUKEQMKLDIPXJEPENEIPWFDLP\r\n" +
"HBQKWJFLSEXVILKYPNSWUZLDCRTAYUUPEITQJEITZRQMMAQNLN\r\n" +
"DQDJGOWMBFKAIGWEAJOISPFPLULIWVVALLIIHBGEZLGRHRCKGF\r\n" +
"LXYPCVPNUKSWCCGXEYTEBAWRLWDWNHHNNNWQNIIBUCGUJYMRYW\r\n" +
"CZDKISKUSBPFHVGSAVJBDMNPSDKFRXVVPLVAQUGVUJEXSZFGFQ\r\n" +
"IYIJGISUANRAXTGQLAVFMQTICKQAHLEBGHAVOVVPEXIMLFWIYI\r\n" +
"ZIIFSOPCMAWCBPKWZBUQPQLGSNIBFADUUJJHPAIUVVNWNWKDZB\r\n" +
"HGTEEIISFGIUEUOWXVTPJDVACYQYFQUCXOXOSSMXLZDQESHXKP\r\n" +
"FEBZHJAGIFGXSMRDKGONGELOALLSYDVILRWAPXXBPOOSWZNEAS\r\n" +
"VJGMAOFLGYIFLJTEKDNIWHJAABCASFMAKIENSYIZZSLRSUIPCJ\r\n" +
"BMQGMPDRCPGWKTPLOTAINXZAAJWCPUJHPOUYWNWHZAKCDMZDSR\r\n" +
"RRARTVHZYYCEDXJQNQAINQVDJCZCZLCQWQQIKUYMYMOVMNCBVY\r\n" +
"ABTCRRUXVGYLZILFLOFYVWFFBZNFWDZOADRDCLIRFKBFBHMAXX";
char[][] map = new char[30][50];
for (int i = 0; i < map.length; i++) {
// System.out.println(ssString.split("\r\n")[i]);
map[i]= ssString.split("\r\n")[i].toCharArray();
}
int cnt = 0;
// 左,右,上,下,左上,右上,右下,左下
int[] offsetN = { 0, 0, -1, 1, -1, -1, 1, 1 };
int[] offsetM = { -1, 1, 0, 0, -1, 1, 1, -1 };
// 遍历这个数组的每一个点,然后以这个点进行8个方向的选取,选出一个方向,就一直按照这个方向走
for (int k = 0; k < 30; k++) {
for (int g = 0; g < 50; g++) {
char start = map[k][g];
// 从八个方向开始遍历,z代表方向,k,g代表坐标,
for (int z = 0; z < 8; z++) {
// 这里的i,j 代表新生成的坐标
for (int i = k + offsetN[z],
j = g + offsetM[z];
i >= 0
&& i < 30 && j >= 0
&& j < 50;
i += offsetN[z], j += offsetM[z])
// map[i][j]:这样就能求出下一个点的坐标,这个坐标比去世的大,
// 并且新生成的坐标小于就坐标,代表选择不能回退
if (map[i][j] > start && (k < i || g < j))
cnt++;
}
}
}
System.out.println(cnt);
}
}
E.平方拆分
public class 平方拆分 {
static int cnt;
public static void main(String[] args) {
dfs(2019, 0);
System.out.println(cnt);
}
static void dfs(int num, int start) {
// 如果数字小于0,那就直接返回
if (num < 0) return;
// 如果等于0,就算一种算法
if (num == 0) {
// System.out.println(start);
cnt++;
}
else
// 从start + 1开始,到这个数的开方结束,
for (int i = start + 1, high = (int)Math.sqrt(num); i <= high; i++)
//1²,2²,3²,一个个的去减,最终结果为0,代表是一种算法,小于零,就算失败
// 0是根节点,它有45个子节点,每个子节点又可划分多个节点
dfs(num - i * i, i);
}
}
F: 最长子序列
import java.util.Scanner;
public class 最长子序列 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String s=scanner.next();
String t=scanner.next();
int p=0;
// 以s字符串的视角进行遍历。如果以t的视角进行遍历,需要记录s视角匹配的位置
for(int i=0;i<s.length();i++){
if(s.charAt(i)==t.charAt(p)){
p++;
if(p==t.length()){
break;
}
}
}
System.out.println(p);
}
}
- 以c的视角进行遍历
import java.util.Scanner;
public class Test_F {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.next(), t = sc.next();
int in = 0; //存储当前匹配字符的下一位索引
int maxlen = 0;//存储匹配长度
for (char c : t.toCharArray()) {
//从上一个字符匹配位置之后开始遍历
for (int i = in; i < s.length(); i++) {
if (s.charAt(i) == c) {
//当前字符匹配成功,结束遍历
maxlen ++; //匹配长度+1
in = i + 1; //更新in
break;
}
}
}
System.out.println(maxlen);
}
}
G:数正方形
- ans[N]=Σ i * i * (n+1-i)
前面 i * i 表示最大边为(n+1-i)的大正方形的个数 - 一道找规律的题目
public class G {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
n--;
long ans=0;
for(int i=1;i<=n;i++){
ans+=(long)i*(long)i*(long)(n+1-i);
ans%=1000000007;
}
System.out.println(ans);
}
}
I 大胖子走迷宫
https://blog.csdn.net/weixin_46239370/article/details/109584332
- 这个没有考虑到自身停留问题,并不好
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
public class 大胖子 {
int n;//n行n列
int k;//每k个小时小明瘦一圈
char[][] maze;//迷宫地图
boolean[][] vis;//地图访问标记
ArrayBlockingQueue<Point> queue;//队列
//位置节点
class Point {
int x;//横坐标
int y;//纵坐标
int time;//时间
Point parent;//从哪个位置节点来的
int a;//将肥胖转换成比常人的厚度,最开始为2,方便计算坐标
public Point(int x1, int y1, Point p,int t,int a1) {
this.x = x1;
this.y = y1;
this.parent = p;
this.time=t;
this.a=a1;
}
}
public 大胖子() {
Scanner sn = new Scanner(System.in);
n = sn.nextInt();
k = sn.nextInt();
// 面具
maze = new char[n][n];
// 是否访问过
vis = new boolean[n][n];
sn.nextLine();
queue = new ArrayBlockingQueue<Point>(n * n);
// 迷宫赋值
for (int i = 0; i < n; i++) {
maze[i] = sn.nextLine().trim().toCharArray();
}
//以上都是初始化
queue.add(new Point(2, 2, null,0,2));//加入初始点
vis[2][2] = true;//标记
Point p=bfs();//获取到达终点的那个节点
System.out.println(p.time);//输出时间
// //展示逆推路线
// while (p.parent != null) {
// System.out.println("x="+p.x+",y="+p.y+",time="+p.time+",a="+p.a);
// p = p.parent;
// }
// System.out.println("x="+p.x+",y="+p.y+",time="+p.time+",a="+p.a);
}
//广度优先搜索
public Point bfs() {
while (!queue.isEmpty()) {
Point p = queue.poll();//取出队头
//更新时间,胖瘦
p.time++;
// 是否到了变瘦的时间
if (p.time % k == 0 && p.a > 0)
p.a--;
//判断这个节点是不是已经是终点了
if (p.x == n - 3 && p.y == n - 3)
return p;
//将四个方向可以移动的位置加入队列
// 下
if (check(p.x, p.y + 1,p) && !vis[p.y + 1][p.x]) {
queue.add(new Point(p.x, p.y + 1, p,p.time,p.a));
vis[p.y + 1][p.x] = true;
}
// 右
if (check(p.x + 1, p.y,p) && !vis[p.y][p.x + 1]) {
queue.add(new Point(p.x + 1, p.y, p,p.time,p.a));
vis[p.y][p.x + 1] = true;
}
// 左
if (check(p.x - 1, p.y,p) && !vis[p.y][p.x - 1]) {
queue.add(new Point(p.x - 1, p.y, p,p.time,p.a));
vis[p.y][p.x - 1] = true;
}
// 上
if (check(p.x, p.y - 1,p) && !vis[p.y - 1][p.x]) {
queue.add(new Point(p.x, p.y - 1, p,p.time,p.a));
vis[p.y - 1][p.x] = true;
}
//如果存在空地但又无法移动,说明小明太胖了,重新加入队列,相当于等待
if(exist(p.x, p.y)) {
queue.add(p);
}
}
//到不了终点,返回空
return null;
}
// 判断p是否能移动到(x,y)
public boolean check(int x, int y,Point p) {
//x是否越界
if (x - p.a >= 0 && x + p.a < n) {
//y是否越界
if (y - p.a >= 0 && y + p.a < n) {
//x,y都正常,因此检查若移动后,自身范围是否存在障碍物,若存在则无法移动
for (int i = x - p.a; i <= x + p.a; i++) {
for (int j = y - p.a; j <= y + p.a; j++) {
if (maze[j][i] == '*')
return false;
}
}
//全部通过检查,可以移动
return true;
}
}
//未通过检查
return false;
}
//检查上下左右当前还有空位
public boolean exist(int x, int y) {
//左
if (x - 1 >= 0) {
if (!vis[x - 1][y]) {
return true;
}
}
//上
if (y - 1 >= 0) {
if (!vis[x][y - 1]) {
return true;
}
}
//下
if (y + 1 < n) {
if (!vis[x][y + 1]) {
return true;
}
}
//右
if (x + 1 < n) {
if (!vis[x + 1][y]) {
return true;
}
}
return false;
}
public static void main(String[] args) {
new 大胖子();
}
}
- 代码的优化
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class 大胖子2 {
static int dx[] = {0,0,1,-1};
static int dy[] = {1,-1,0,0};//上下左右四个方向
static char [][]c;
static int N;
static int k;
static int bo[][];//用于标记某一点是否走过。因为可以原地不动,所以不会出现走到某一点又回头能使时间更短的情况。
static int fat[] = {2,1,0};//用于记录当前的体型,,(x+fat[],y+fat[]) 表示身体的边界
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
k = sc.nextInt();
bo = new int[N][N];
c = new char[N][N];
for(int i = 0; i <N; i ++)
c[i] = sc.next().toCharArray();//赋值,初始化
System.out.println(bfs(2,2,0));
}
private static int bfs(int x, int y, int time) {
Queue <st>q = new LinkedList<st>();
q.add(new st(x,y,time));//先给起点加进去,从起点开始bfs
while(!q.isEmpty()) {
bo[x][y] = 1;//先给七点标记。
st t = q.poll();
if(t.x == N - 3 && t.y == N - 3)
return t.time;
// 这时候是个胖子,可以等待
if (t.time/k<2) {
//表示原地不动得情况,,坐标不变time+1.
q.add(new st(t.x,t.y,t.time+1));
}
int g = t.time/k >= 2 ? 0 : fat[t.time/k];//表示体型。
//g表示身体中心点和边界得距离。用于后面检查边界是否碰到障碍物或者越界。
for(int i = 0; i < 4; i ++) {
//访问该点得上下左右四个位置。
int u = t.x+dx[i];
int v = t.y+dy[i];
//(u-g,v-g)表示大胖子得左上角。。判断边界是否越界 和 该点是否已经被访问过
if(u - g >= 0 && u + g < N && v - g >= 0 && v + g < N && bo[u][v] == 0) {
boolean boo = true;
for(int a = u - g; a <= u + g; a ++)
for(int b = v - g; b <= v +g; b ++)
if(c[a][b] == '*')
boo = false;//检查整个身体。如果有哪一个点是障碍物,说明不能往这个位置移动,下面不再执行
if(boo) { //如果可以往这个位置走
if(u == N - 3 && v == N - 3)//判断这个位置是不是终点
return t.time + 1; // 注意返回time+1.。因为向这个点移动用的时间没有加上
q.add(new st(u,v,t.time+1));//如果不是终点,这个点加入队列
bo[u][v] = 1; //标记这个点是已经被访问过得。。
}
}
}
}
return -1;
}
}
//注意定义结构体要有三个状态,,(x,y)表示当前身体中心点的位置。time表示当前用的时间。。
class st
{
int x, y, time;
st(int x, int y, int time)
{
this.x = x;
this.y = y;
this.time = time;
}
}