一些蓝桥杯的简单模拟题目

3.xx大学的模拟题

1.基础知识

  • 顺序
  • 选择
  • 循环
  • 数组宁符数组
  • 结构体
  • 函数
  • 全排列
  • multimap

1.*梦里的难题

生化危机血腥暴力的场面对小星星的冲击很大,晚上频繁地做起了梦,梦里他担负起拯救世人消灭僵尸的重任,眼看就能拿到消除 T 病毒的解药还世界清静,但 T 病毒人工智能电脑挡住了星星的去路,它声称研制出 T 病毒的目的是因为察觉人类智力退化,只有聪明的人才能存活下来,如果想要拿到解药,必须回答出下面这个难题:
有 N(1≤N≤100000)个数字(由 1 到 K 组成,1≤K≤10000),排成一列形成数字串,例如 1,5,3,2,5,1,3,4,4,2,5,1,2,3 它包含了很多的子序列,比如(5)、(1,3,2)、(1,5,3)、(3,4,1,3),请思考该列数字串不包含的最短的由 1 到 K 组成的的子序列长度是多少?

思路:

若有长度为1的子序列存在,则题中数的序列中必有k个数的一种全排列(可不连续)。同理,若有长度为2的子序列存在,则在第一个全排列后必再有一组k个数的全排列(可不连续),则只需要扫描n个数,能找到几组全排列(可不连续),即为答案。

2.幼儿园小朋友们的难题

https://blog.csdn.net/qq_45159762/article/details/104234100

输入

输入有多组数据。每组输入一个句子(一定包含数字字符,可能包含空格),长度小于256,占一行

输出

输出对应有多行,每行输出所找出的最大的那个非负整

样例输入:

&&12345aBsdDkjie64skjd5lk
3*2&&0%%%00B58CD000000b
a000b0000000c000

样例输出

12345
58
0

public class 幼儿园小朋友们的难题1016 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		while(true) {
			
			String ss = scanner.nextLine();
			if (ss.equals("")) {
				break;
			}
			char[] ssArray = ss.toCharArray();
			//每行最大的数字
			String max = "0";
			//对数组里的每个字母进行判断
			for (int i = 0; i < ssArray.length; i++) {
				//判断这个字母是否是数字,数字不要以0为开头
				if (ssArray[i]>'0' && ssArray[i] <='9' ) {
					String b ="";
					//判断这个字幕的下一个字母是否是数字,直到不是
					//数字为止,这里的i的下标值很巧妙
					while(ssArray[i]>='0' && ssArray[i] <='9') {
						b +=ssArray[i++];
					}
					//现在b里是一连串数字
					
					if (b.length()>max.length() ||
						(b.length() == max.length() && (b.compareTo(max)>0))) {
						//如果b里的数字大于max的值
						max = b;
					}
				}
			}
			System.out.println(max);
		}
	}
}

3.池塘的水草1017

输入

输入有多行。第一行包含一个整数N(0 < N < 1000),表示有N组数据。

接下来N行,每行有一个整数m(1<m<109),表示m天长满池塘的水面。

输出

每组数据输出一个整数,代表水草第几天能长到池塘水面的一半。

样例输入

2
10
2

样例输出

9
1
import java.util.Scanner;

public class 池塘的水草1017 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		for (int i = 0; i < n; i++) {
			int m = scanner.nextInt();
			System.out.println(m-1);
		}
	}
}

4.1018: 青岛大虾

输入

输入包含多组数据。

每组包含两个数据,占一行。第一个数是一个浮点数area(30<=area<=800),表示每套住房的建筑面积,第二个数是一个整数N(100<= N <=1000),表示每套住房每平米的价格,即每平米卖多少只大虾,大虾的价格都是按市场价38元/只计算。

输出

对应每组输入数据,输出购买该住房需要实际花费的总价(单位:元)

样例输入

90.12 170
120 130
204.51 200

样例输出

582100
592800
1554200
import java.util.Scanner;
public class 青岛大虾1018 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		String ss = scanner.nextLine();
		while (!ss.equals("")) {
			String[] ss1 = ss.split(" ");
			float area = Float.valueOf(ss1[0]);
			int price = Integer.valueOf(ss1[1])*38;
			int sum = (int) (price*area);
			int shengyu = sum%100;
			//取零是重点
			sum = sum- shengyu;
			System.out.println(sum);
	     	ss = scanner.nextLine();		
		}	
	}
}

2基本算法

  • 枚举
  • 模拟
  • 递归
  • 分治
  • 排序
  • 构造前缀和
  • 差分
  • 双向搜索

1.枚举

1. 1027: 你的QQ多少级了?

题目描述

QQ等级是2003年腾讯公司推出的QQ中的一种制度。最早是以小时来计算的,那段时间,绝大部分QQ用户都在挂QQ。随后就有不少媒体指责其浪费能源。在有关部门的介入下,腾讯公司将QQ等级变为以天为单位,每天只要在线两个小时就算一天。 半小时以上、两小时以下则记为半天。QQ等级最先开始的样子是星星,4个星星等于一个月亮,4个月亮等于一个太阳。4个太阳等于一个皇冠。(即:1个星星为1级,1个月亮为4级,1个太阳为16级,1个皇冠为64级。)一开始增加一个星星只用几天,到后面就要越来越多的天数来升级了。

img

用户可以在好友资料的浮出Tips显示中查看好友的在线等级,也可以在主面板自己头像的浮出Tips中查看自己的在线等级。用户到达每个等级需要的总天数可用如下的计算公式计算:

Days = Level * Level + Level * 4

现在你需要做的工作是根据给出的天数,计算用户的当前等级。

输入

输入仅一行,为一个非负整数Days,表示用户的活跃天数,输入数据在int表示的范围内。

输出

输出仅一行:一个整数表示用户的等级。

样例输入

867

样例输出

27
import java.util.Scanner;

public class QQ等级 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		long dags = scanner.nextLong();
		int level = 1;
		long sum = level*(level+4);
		//注意边界值的判断
		while (sum<=dags) {
			level++;
			sum = level*(level+4);
		}
		System.out.println(--level);
	}
}

2.模拟

  • 按照题目给的操作,用代码依次描述出来即可。
1.1024: 学霸猫

在我认识它的时候,它就已经叫学霸猫了,虽然我不知道它名字的由来,但在石大这种地方被冠以学霸之名。它经常会光顾正在上课的教室,并跟同学们一起耐心听讲,学校的教学楼、机房里到处都留下它的倩影,相信它将来会成为一个Doctor Cat。有心的同学记录下了它出现的课堂名称和出现时间。聪明的学霸猫是非常擅长学习的,即使在打盹的时候,也是在学习。它在某个课堂停留的时间越长,学习效果就越好。请你计算一下它哪门课学的最好吧(我不会告诉你它经常去听金老师的高等数学哟)。

输入

输入有多行。

每行包含三个数据,分别表示课堂名称(长度不超过30个字符),学霸猫的出现时间和离开时间,这两个时间都是指同一天。课堂名称保证不重复。

输出

输出学霸猫学习效果最好的一门课的名称和时长(具体格式见样例输出),占一行,两个数据间以空格分隔,末尾没有空格。

样例输入

programming 14:00 15:30
math 8:00 8:10

样例输出

programming 1:30
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class Subject{
	String name;
	String begin;
	String over;
	int time;
}
public class 学霸猫 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		String line = scanner.nextLine();
		Subject reSubject = new Subject();
		while (!line.equals("")) {
			String[] split = line.split(" ");
			Subject subject = new Subject();
			subject.name = split[0];
			subject.begin = split[1];
			subject.over = split[2];
			String[] split2 = subject.begin.split(":");
			String[] split3 = subject.over.split(":");
			int timebegin = Integer.valueOf(split2[0])*60+Integer.valueOf(split2[1]);
			int timeover = Integer.valueOf(split3[0])*60+Integer.valueOf(split3[1]);
			int time = timeover-timebegin;
			subject.time = time;
			if (time>reSubject.time) {
				reSubject = subject;
			}
			line = scanner.nextLine();
		}
		String time = reSubject.time/60+":"+ reSubject.time%60;
		System.out.println(reSubject.name+" "+time);
	}
}

3.递归

https://segmentfault.com/a/1190000038392459

https://developer.51cto.com/art/202007/620693.htm

  • 阶乘
  • 斐波那契数列

https://zhuanlan.zhihu.com/p/108269159

  • 爬楼梯的理解

https://www.jianshu.com/p/74cdb5d8d264

  • 汉诺塔

https://blog.csdn.net/liujian20150808/article/details/50793101

* 1.1261: 放苹果

题目描述

把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。

输入

第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。

输出

共t行,每行一个整数,表示对应有多少种不同的方法。

样例输入

1
7 3

样例输出

8
import java.util.Scanner;

public class 放苹果 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int num = scanner.nextInt();
		for (int i = 0; i < num; i++) {
//			String line = scanner.nextLine();
			int apple = scanner.nextInt();
			int plate = scanner.nextInt();
			System.out.println(putApple(apple,plate));
		}
	}
	
	 public static int putApple(int m, int n) {
		 

    // 递归出口:有0个苹果 || 只有1个盘子
     if (m == 0 || n == 1)
         return 1;
     if (n>m) // 盘子比较多,肯定有空盘子,去掉必空的盘子
         return putApple(m, m);
     else // 苹果比较多:
         // 1:至少有一个空盘子,拿掉这个空盘子
         // 2:每个盘子都有苹果,各拿掉一个苹果(极限是最少的有1个苹果)
         return putApple(m, n - 1) + putApple(m - n, n);
	 }
}
  • 递归算法的练习题

https://www.cnblogs.com/liuzhen1995/p/11748881.html

https://zhuanlan.zhihu.com/p/59685884

1.

4.分治

https://blog.csdn.net/mingyuli/article/details/79608871

  • 汉诺塔

https://www.jianshu.com/p/c26ce803b187

https://blog.csdn.net/zandaoguang/article/details/76889284

https://www.zhihu.com/question/24385418

public class 汉诺塔 {
	
    public static void main(String[] args) {
        hanoiTower(6, 'A', 'B', 'C');
    }

    /**
               * 汉诺塔问题
     *
     * @param num 有多少层
     * @param a   柱子1
     * @param b   柱子2
     * @param c   柱子3
     */
    

    public static void hanoiTower(int num, char a, char b, char c) {
        if (num == 1) {
            System.out.println("第1个盘从 " + a + " -> " + c);
        } else {
        	/*

        	奇数时:
        		第1个盘子:A-->C
        		第2个盘子:A-->B
        		第1个盘子:C-->B
        		//这是腾出了位置,c空了出来
        		第3个盘从 A ->C
        		第1个盘从 B -> A
        		第2个盘从 B -> C
        	偶数时:
        		第1个盘子:A--->B
        		第2个盘从: A--> C
        		第1个盘从 B -> C
        		//这是腾出了位置,b空了出来
        	 	第3个盘从 A -> B
        	 	第1个盘从 C -> A
        	 */

        	
            hanoiTower(num - 1, a, c, b);
            
            System.out.println("第" + num + "个盘从 " + a + " -> " + c);
            hanoiTower(num - 1, b, a, c);
        }
    }
}
import java.util.Scanner;

public class Hanoi2 {

    static int m = 0;// 标记移动次数

    // 实现移动的函数

    public static void move(int disks, char N, char M) {
        System.out.println("第" + (++m) + " 次移动 : " + " 把 " + disks + " 号圆盘从 " + N + " ->移到->  " + M);
    }

    // 递归实现汉诺塔的函数

    public static void hanoi(int n, char A, char B, char C) {

        if (n == 1)// 圆盘只有一个时,只需将其从A塔移到C塔

            Hanoi2.move(1, A, C);// 将编b号为1的圆盘从A移到C

        else

        {
            // 否则

            hanoi(n - 1, A, C, B);// 递归,把A塔上编号1~n-1的圆盘移到B上,以C为辅助塔

            Hanoi2.move(n, A, C);// 把A塔上编号为n的圆盘移到C上

            hanoi(n - 1, B, A, C);// 递归,把B塔上编号1~n-1的圆盘移到C上,以A为辅助塔

        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        char A = 'A';

        char B = 'B';

        char C = 'C';
        System.out.println("******************************************************************************************");
        System.out.println("汉诺塔问题(把A塔上编号从小号到大号的圆盘从A塔通过B辅助塔移动到C塔上去---山东科技大学昝道广");
        System.out.println("******************************************************************************************");
        System.out.print("请输入圆盘的个数:");
        int n = in.nextInt();
        Hanoi2.hanoi(n, A, B, C);
        System.out.println(">>移动了" + m + "次,把A上的圆盘都移动到了C上");
        in.close();
    }

}

1.1031: 苹果分级

今年老王家的苹果丰收了,为了能卖个好价钱,老王把苹果按直径大小分等级出售。这么多苹果如何快速的分级,可愁坏了老王。现在请你编写一个程序来帮助老王模拟苹果分级的操作吧,要求一级果的直径大于等于70毫米,二级果的直径是6960毫米,三级果的直径是5950毫米,小于50毫米的算四级果。

输入

若干个整数,表示每个苹果的直径,当输入直径小于20时表示结束。苹果的直径最小为20,最大为120。

输出

输出有两行:第一行输出苹果总个数;第二行输出一级果、二级果、三级果、四级果的个数,中间用空格分隔,四级果后面无空格。

样例输入

67 34 85 58 32 54 59 60 55 42 51 0

样例输出

11
1 2 5 3
import java.util.Scanner;

public class 分治算法 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		String hang = scanner.nextLine();
		int one = 0;
		int two = 0;
		int three = 0;
		int four = 0;
		String[] split = hang.split(" ");
		for (int i = 0; i < split.length-1; i++) {
			int num = Integer.valueOf(split[i]);
			if (num>=70) {
				one++;
			}else if (num>=60) {
				two++;
			}else if (num>=50) {
				three++;
			}else {
				four++;
			}
		}
		
		System.out.println(split.length-1);
		System.out.println(one+" "+two+" "+three+" "+four);
	}
}

5.贪心

1. 1087: 零钱兑换

题目描述

小油瓶拿着100元去买糖吃,买了糖后要找零时,发现店里只剩下1元、2元和5元的纸币了。找回来一大堆零钱确实很烦人,所以小油瓶要求店员找给他的纸币的数量必须是最少的。 已知需要找还的钱的数额,同时店里有充足的1、2、5元纸币供找兑。编写一个程序,计算以最少数量的纸币凑出找零的数额时,各种纸币的使用数量。

输入

程序的输入为若干行,每行为一个整数,每个整数代表每次需找还的零钱的数量n(0<n<100),输入0则代表输入结束。

输出

根据每行输入的需找还的零钱的数量,程序计算相应的最小数量组合,并将纸币的使用数量以1元、2元、5元的顺序在相应行中输出,中间以一个空格相隔,每行输入对应一行输出。

样例输入

8
12
0

样例输出

1 1 1
0 1 2

提示

12元最好的组合为0张1元,1张2元,2张5元,所以对应的输出为0 1 2

import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

import javax.print.attribute.standard.NumberUpSupported;

public class 零钱兑换 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		List<Integer> nums = new LinkedList();
		int num = scanner.nextInt();
		while (num!=0) {
			nums.add(num);
			num = scanner.nextInt();
		}
		for (int i = 0; i < nums.size(); i++) {
			 num = nums.get(i);
			 int five = num/5;
			 int two = num%5/2;
			 int one = num%5%2;
			 System.out.println(one+" "+two+" "+five);
		}
	}
}

6.排序

1.1051: 奥运会跳水比赛

https://www.e-learn.cn/topic/3276295

`


import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
//定义一个类,用来代表每个选手
class People{
	String name;
	float[] scores = new float[5];
	float nandu;
	float sum;
}
public class 奥运会跳水比赛 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int num = scanner.nextInt();
		//声明数组
		People[] peoples = new People[num];
		//消除回车换行的影响
		scanner.nextLine();
		for (int i = 0; i < num; i++) {
			String hang = scanner.nextLine();
			String[] split = hang.split(" ");
			//数组赋值
			peoples[i] = new People();
			peoples[i].name = split[0];
			//选手得分赋值
			for (int j = 1; j < split.length-1; j++) {
				peoples[i].scores[j-1] = Float.valueOf(split[j]);
			}
			//选手成绩排序
			Arrays.sort(peoples[i].scores);
			//难度系数赋值
			peoples[i].nandu = Float.valueOf(split[6]);
//			求出总分
			peoples[i].sum = (peoples[i].scores[1]+peoples[i].scores[2]
					+peoples[i].scores[3])*peoples[i].nandu;	
		}
		//冒泡排序,求出序号
		for (int i = 0; i < peoples.length-1; i++) {
			for (int j = 0; j < peoples.length-i-1; j++) {
				if (peoples[j].sum<peoples[j+1].sum) {
					People people = peoples[j];
					peoples[j] = peoples[j+1];
					peoples[j+1] = people;
				}
			}
		}
		//输出排名。注意保留一位小数
		for (int i = 0; i < peoples.length; i++) {
			System.out.println(i+1+" "+peoples[i].name+" "+Math.round(peoples[i].sum*10)/10.0);
		}
	}
}

7.*倍增

  • 最近公共祖先(Least Common Ancestors,LCA)问题详解

https://blog.csdn.net/ywcpig/article/details/52336496

  • 倍增法

https://blog.csdn.net/blaze003003/article/details/81084954

* 1.小刚传说

https://blog.csdn.net/jeryjeryjery/article/details/52853017

题目描述

众所周知,刘小刚是海亮中学的金牌教练,然而世人并不知道他的传奇经历,以及那个曾经轰动世界的名字sharpland。
2003年,美国研究团队在量子计算机的研制上取得了重大突破,一旦美国成功研发出量子计算机,一切加密手段都将形同虚设。当此之时,国内第一黑客sharpland秘密潜入美国中央情报局,得知关于量子计算机的研究成果封存于五角大楼计算机群之中。经过一周的0Day挖掘,sharpland成功侵入计算机群,却发现这里的文件保护机制非同寻常。
五角大楼计算机群的文件形成了树结构,且树的形态随时间变化。已知初始时刻树上仅有一个根节点1,当成功拷贝结点i上的文件时,树上会新增结点i+1,它的父亲为一个已存在的结点。树的大小增加为n时便会停止。
sharpland通过之前挖掘的0Day成功推算出了所有新增结点的父亲,为了破解文件保护系统,他需要在每次新增结点后新增的结点i和上一次新增的结点i-1的路径长度。

输入

第一行,一个整数n表示最终树的大小。
接下来n-1行,每行一个整数表示新增节点的父亲。

输出

共n-1行,每行一个整数表示答案。

样例输入

【样例1】
6
1
2
2
1
5
【样例2】
10
1
1
3
1
2
3
6
1
8

样例输出

【样例1】
1
1
2
3
1
【样例2】
1
2
1
3
3
4
5
4
5

提示

对于30%的数据,n≤100
对于60%的数据,n≤2000
对于100%的数据, 2≤n≤200000

【后记】
sharpland成功窃取数据的那一刻,中央情报局察觉到了数据失窃并发布全球通缉令,sharpland隐姓埋名逃会国内,以刘小刚为化名,以高中竞赛教练为掩护,生活至今。然而第一黑客sharpland之名早已响彻世界。

2.快速幂

https://www.jianshu.com/p/45a2f9e8391a

快速幂算法推导(详解)

https://blog.csdn.net/Ven21959/article/details/99671654

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A6tqetFB-1622898105633)(蓝桥杯比赛.assets/20190816103145244.png)]

题意:

计算a^n % b,其中a,b和n都是32位的整数。

样例:

例如 2^31 % 3 = 2
例如 100^1000 % 1000 = 0

挑战:

O(logn)
public class 快速幂算法{
	static int power(int a,int b) {
		int ans = 1;
//		当b不为0时,继续循环
		while(b!=0) {
			//把b转为二进制进行运算,如果是偶数,b的最后一位是0,否则就是1,这样就可以判断出基数,偶数
			if((b&1)!=0){
				ans=ans*a;//若指数为奇数,将分离出来的一次方底数收集好 
			}
			//若指数为偶数数
			a=a*a; //底数变为原来的平方 
			b>>=1; //指数变为原来的一半 .b要转为二进制进行运算
			System.out.println(b);
		}
		return ans;
	}
	
	public static void main(String[] args) {
		System.out.println(power(3, 10));
	}

}

8.构造

https://blog.csdn.net/wtq1993/article/details/52910319

1.*数对

题目描述

给定一个正整数n,现在有一个由数对(a,b)组成的序列,其中1<=a<=n,|b|<=n。|b|表示b的绝对值。该序列称为优美序列,当且仅当以下条件同时满足:
1、所有的数对都不相同。
2、对于每一个有数对(a,b),a和|b|不相同。
3、对于每一个有数对(a,b),若b>0,则它之前一定存在一个数对(a,b)满足a=b且b=0;
4、对于每一个有数对(a,b),若b<0,则它之前一定不存在一个数对(a,b)满足a=-b且b=0;
5、对于所有相邻的数对(a1,b1),(a2,b2),满足b1和b2不同时为正整数且不同时为负数且不同时为0;
请你求出最长的优美的序列的长度。
例如,当n=2时,其中一个最长的优美的序列为(2,-1), (1,0), (1,-2), (2,1), (2,0), (1,2), 长度为6。

输入

仅一行,一个正整数n。

输出

输出一个整数,如题所述。

样例输入

2

样例输出

6

提示

对于20%的数据,n<=4。
对于80%的数据,n<=106。
对于100%的数据,n<=108。

9.前缀和

1.Tower

题目描述

平面上有N个整数坐标点。如果将点(x0,y0)移动到(x1,y1),则需要的代价为|x0-x1|+|y0-y1|。求使得K(K=1,……,N)个点在同一位置上最少需要的代价。

输入

第一行一个正整数N。

接下来N行,每行两个正整数xi和yi,为第i个点的坐标,不超过106。

输出

输出共N行,第i行为使得有i个点在同一位置的最少代价。

样例输入

4
15 14
15 16
14 15
16 15

样例输出

0
2
3
4

提示

对于100%的数据,满足1≤N≤50。

思路:

找到所有相关点(x,y坐标的界限)所组成的矩形,然后一个个比较,找到最小的值。

import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

//定义一个结点,代表着坐标
class Node{
	int x;
	int y;
	public Node(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}
	
}
public class Tower {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int begin = scanner.nextInt();
//		定义一个集合,把所有的点存贮起来
//		System.out.println(1);
		scanner.nextLine();
		List<Node> list = new LinkedList<Node>();
		for (int i = 0; i < begin; i++) {
			String[] ss = scanner.nextLine().split(" ");

			Node node = new Node(Integer.valueOf(ss[0]), Integer.valueOf(ss[1]));
			list.add(node);
		}
//		//初始化区间的值
		int minx = list.get(0).x;
		int miny = list.get(0).y;
		int maxx = list.get(0).x;
		int maxy = list.get(0).y;
		for (int i = 0; i < begin; i++) {
			//每一次遍历,也就代表着一次输出
			int x = list.get(i).x;
			int y = list.get(i).y;
			//代表着代价的最小值
			int min = 9999999;
			
			
			//找到所有的点所在的矩形区间
			if (x<minx) {
				minx = x;
		    }
			if (y<minx) {
				miny = y;
			}
		
			if (x>maxx) {
				maxx = x;
			}
			if (y>maxy) {
				maxy = y;
			}
			//开始遍历这个矩形区间上的所有点
			for (int j = minx; j <= maxx; j++) {
				for (int j2 = miny; j2 <= maxy; j2++) {
					//把集合里的点取出来,一一和矩形区间的点相减
					//代表着一个临时值
					int temp = 0;
					
					for (int k = 0; k<=i; k++) {
						temp+=Math.abs(list.get(k).x-j)+Math.abs(list.get(k).y-j2);
					}
					//在矩形上的这个点的代价是最小的
					if(temp<min) {
						min = temp;
					}
				}
			}
			System.out.println(min);	
		}
	}
}

10.差分

1.Fancy 的区间

省选终于考完了,但是还是不出成绩,Fancy 非常焦急而忧伤的等待着。

闲着无聊的 Fancy 打开书包拿出了一张纸和一支笔,在纸上画了一行n个格子。Fancy 每次想两个数字,然后把这两个数字之间(包括这两个数字)的格子涂黑。如果有格子已经涂过了,Fancy 还会再涂一遍(反正都是黑的)。突然成绩出来了,Fancy 跑去听成绩了,不小心把纸掉在了地上。现在 Fancy 想知道还有哪些区间没有涂黑,你能帮帮她吗?

输入

第一行两个数n和 m,n表示格子数目,m表示区间对数。 接下来m行,每行两个数x和y,表示将x 到y之间的格子涂黑。

输出

输出若干行,每一行两个数x和 y,中间用空格隔开,表示从x到 y 之间是白色的。

注:
1.从x到 y 表示包括x和 y 的中间一整段;
2.输出的区间必须合法(x≤y)且无重复;
3.如果只有一个点x,则输出 x x;
4.输出时区间按左端点排序,且不允许出现前后两个区间可以合并的情况,如 1 3 和 4 5 要输出 1 5;
5.若所有区间都被覆盖,则不用输出;

样例输入

10 3
1 3
2 5
8 9

样例输出

6 7
10 10

提示

对于100%的数据,1≤n≤1000000,1≤m≤500000,1≤x≤y≤n。

import java.util.Scanner;

public class Fancy的区间 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		String ss = scanner.nextLine();
		String[] ss1 = ss.split(" ");
		int n = Integer.valueOf(ss1[0]);
		int m = Integer.valueOf(ss1[1]);
		//定义一个数组,从一开始计数,末尾多得一个是防止数组越界
		int[] arr = new int[n+2];
		//在末尾多得那个不能访问
		arr[n+1] = 1;
		int zuo;
		int you;
		for (int i = 0; i < m; i++) {
		    ss = scanner.nextLine();
		    ss1 = ss.split(" ");
		    //左区间
			zuo = Integer.valueOf(ss1[0]);
			//右区间
			you = Integer.valueOf(ss1[1]);
			//将这些区间里的空间进行赋值,代表不能访问
			for (int j = zuo; j <=you; j++) {
				arr[j] = 1;
			}
		}
		//开始输出结果,从一开始
		for (int i = 1; i <= n; i++) {
			if (arr[i] == 0) {
				//保证记录
				int j = i;
				//看看i后面的空间能否访问
				while (arr[++i] == 0);
				//这样的话代表不能访问,说明它只有一个
				if (j == i-1) {
					System.out.println(j+" "+j);
					return;
				}
				//这个区间的值都是能访问的
				System.out.println(j+" "+(i-1));
			}
		}
	}
}

11.双向搜索

1.数据结构_堆栈_判断回文数

要求:由于输入的一个回文数可能无穷大,所以用单链表存储该数,将用户输入的数以一个单链表的方式存储,从头扫描该单链表,将前面的一半元素入栈,若元素总个数为奇数,则跳过中间的那个元素,然后开始循环:边退栈边在单链表中后移指针,若当前栈顶元素与单链表中当前节点的值域不相等,则退出循环。最后如果栈空且链表比较完毕,则是回文数,否则不是回文数。

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;

public class 数据结构_堆栈_判断回文数 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		String ss = scanner.nextLine();
		List list = new ArrayList();
		while (!ss.equals("")) {
			for (int i = 0; i < ss.length(); i++) {
				list.add(ss.charAt(i));
			}
			ss = scanner.nextLine();
		}
		
		
		Stack stack = new Stack();
		
		int size = list.size();
		//有偶数个数字
		if (size%2 == 0) {
			for (int i = 0; i < size/2; i++) {
				stack.push(list.get(i));
			}
			
			for (int i = size/2; i < size; i++) {
				if (stack.pop() != list.get(i)) {
					System.out.println("0");
					return;
				}
				
			}
			System.out.println("1");
		}else {
			for (int i = 0; i < size/2; i++) {
				stack.push(list.get(i));
			}
			
			for (int i = size/2+1; i < size; i++) {
				if (stack.pop() != list.get(i)) {
					System.out.println("0");
					return;
				}
				
			}
			System.out.println("1");
		}
	}
}
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值