第十届蓝桥杯 国赛 java C组

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;
    }
}

j:估计人数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值