编程题目1

select 查询结果    如: [学号,平均成绩:组函数avg(成绩)]
from 从哪张表中查找数据   如:[涉及到成绩:成绩表score]
where 查询条件    如:[b.课程号='0003' and b.成绩>80] BETWEEN       IS NULL        NOT  IN AND OR
group by 分组    如:[每个学生的平均:按学号分组]
having 对分组结果指定条件    如:[大于60]
order by 对查询结果排序    如:[增序: 成绩  ASC / 降序: 成绩 DESC];
limit   使用limt子句返回topN(对应这个问题返回的成绩前两名)如:[ limit  2 ==>0索引开始读取2]
limit==>0索引开始 [0,N-1]
组函数: 去重 distinct()  统计总数sum()   计算个数count()  平均数avg()  最大值max() 最小数min() 

多表连接: 
内连接等值链接,只显示关联数据,自链接   FROM tablea AS A INNER JOIN tableb AS B  ON A.key = B.key;  
左外连接就是左表参照显示所有,无关联行null  LEFT OUTER JOIN Orders ON Customers.cust_id = Orders.cust_id;
右连接right join  
组合两个查询union(无重复(过滤去重))union all(有重复[不过滤去重])

视图:虚拟表本身不包含数据,操作和普通表一样,使用实际表一部分,给用户视图权限保证数据安全
存储过程:一系列SQL操作的批处理,代码封装,复用,预先编译性能好
触发器:触发器会在某个表执行以下语句时而自动执行:DELETEINSERTUPDATE  CREATE TRIGGER 语句创建触发器
查找班级语文英语不及格的人数
SELECT 
	class as 班级ID,
	sum(case when 语文score < 60 then 1 else 0 end) as 不及格人数,
	sum(case when 英语score < 60 then 1 else 0 end) as 不及格人数
FROM
	class_score
GROUP BY
	class;0
	
查课程1比课程2高学生学号
SELECT t1.sid,t1.score,t2.score
FROM
	(select sid,score
	from sc
	where cid = '01') as t1
JOIN
	(select sid,score
	from sc
	where cid = '02') as t2
ON t1.sid = t2.sid and t1.score>t2.score

查询平均成绩大于60分的同学的学号和平均成绩
SELECT sid,AVG(score) AS AVG
FROM sc
GROUP BY sid
having avg(score)>60

查询所有同学的学号、姓名、选课数、总成绩
SELECT t1.sid,t1.sname,t2.cnt,t2.total_score
FROM
	(SELECT sid,sname
	FROM student
	GROUP BY sid) AS t1
LEFT JOIN
	(SELECT sid,COUNT(*) AS cnt,SUM(score) AS total_score
	FROM sc
	GROUP BY sid) AS t2
ON t1.sid = t2.sid

查询所有课程成绩小于60分的同学的学号、姓名
SELECT DISTINCT s.sid,s.sname
FROM student AS s
JOIN(
	SELECT sid
	FROM sc
	GROUP BY sid
	HAVING MAX(score) < 60
)AS t
ON s.sid = t.sid

查询没有学全所有课的同学的学号、姓名;
SELECT s.sid,s.sname
FROM student AS s
LEFT JOIN sc	
on s.sid = sc.sid
GROUP BY s.sid
HAVING COUNT(sc.cid)<3

查询学生的总成绩并进行排名
SELECT 
	sid
	,SUM(score) AS total_score
	,rank() over (ORDER BY SUM(score) DESC) AS srank
FROM sc 
GROUP BY sid

找姓氏包含字符:en的所有员工
SELECT
    employee_id,
    first_name,
    last_name
FROM
    employees
WHERE
    last_name LIKE '%en%';
    
触发器是一种特殊的存储过程,就相当于是一个事件的触发装置,它在试图更改触发器所保护的数据时自动执行。
要创建触发器来使班级表中的班内学生数随着学生的添加自动更新,代码如下:
create trigger tri_stu after insert
on student for each row
begin
declare c int;
set c = (select stuCount from class where classID=new.classID);
update class set stuCount = c + 1 where classID = new.classID;

查重名的名字
SELECT * FROM employer WHERE name IN 
(SELECT name FROM employer GROUP BY name HAVING COUNT(*) > 1)

like%:匹配任字符出现任次数,_ 匹配单个字符。jia%匹配开头,可以走索引(%value%走全表),jia_ jia开头且后边只有一个字符,Lucy/_%' escape转义'/以Lucy_开始


select * from user where name like '\[%' escape '\' and name like '%\]' escape '\'

2、魔法元素平衡

public class mofa {
    public static long f(long a,long b,long c,long d){
        long sum = a + b + c + d;
        long avl = sum / 4;
        for (long x = avl; x >= 0; x--) {
            long left = sum - 4 * x;
            long right = 0;
            if (x - a > 0) right += x - a;
            if (x - b > 0) right += x - b;
            if (x - c > 0) right += x - c;
            if (x - d > 0) right += x - d;
            if (left >= right) {
                return 4*x;
            }
        }
        return -1;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        String[] s1 = s.split(" ");
        long a = Long.parseLong(s1[0]);
        long b = Long.parseLong(s1[1]);
        long c = Long.parseLong(s1[2]);
        long d = Long.parseLong(s1[3]);
        System.out.println(f(a,b,c,d));
    }
}

public class mofa {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()){
            long[] eles = new long[4];
            int sum = 0;
            for (int i = 0; i < 4; i++) {
                eles[i] = in.nextLong();
                sum += eles[i];
            }
            long avl = sum/4;
            long l = 0,r = 0;   //l累加比avl小的,r累加比avl大的
            for (int i = 0; i < 4; i++) {
                long sub = eles[i]-avl;
                if(sub<0)
                    l -= sub;   //由于sub小于0,所以用-=
                else if(sub>0)
                    r += sub;
            }
            long x = 2*l-r;     //比较用R去比L,够不够
            if (x<=0)
                System.out.println(avl*4);  //小于等于0说明是够的
            else
                System.out.println((long)(avl-Math.ceil(((double)x)/4))*4);
            //大于0说明不够,那么输出avl-差值除以4向上取整
        }
    }
}

3、排序

比如:1 3 6 4 5 2
我们观察最大的数6不用移动,
a.6右边的数全部要移动,就是1+1+1=3次(移动的次序不一定,但是次数一定是3)
b.6左边的数,因为排序后和6挨着的一定是4 5,所以前面的两个数不是4 5这样的排序的话一定是移动1+1=2次
c.所以一共需要移动3+2=5次。
综上算法:
1.我们先需要找到最大数所在的序号
2.最大数右边数的个数为a
3.最大数左边的数需要按照自然数的顺序排到N------(N-3, N-2, N-1, N)-----违反规则的个数为b,例如(1 2 5 6 4 3),左边12不满足规则的,所以b为2
3.最后的排序的个数为a+b
public class Main1 {
    public static void main(String[] args) {
    	//输入N
        Scanner ss1 = new Scanner(System.in);
        int N = ss1.nextInt();
		//连续输入n个数,并存入数组中
        Scanner ss2 = new Scanner(System.in);
        String[] str = ss2.nextLine().split(" ");
        int[] a = new int[str.length];
        for(int i = 0;i<str.length;i++){
            a[i] = Integer.parseInt(String.valueOf(str[i]));
        }

		//计算次数
        int pp = fun(N,a);
        System.out.println(pp);
    }
	//函数
    private static int fun(int n, int[] arr) {
    	//1.得到一个有序的数组brr
        int[] brr = arr.clone();   
        Arrays.sort(brr);
        int j = n-1; //记录brr的位置
        int sum = 0; //记录移动次数
        for(int i = n-1;i>=0; i--){
            if(arr[i] == brr[j]){
                j--;//相等时brr的j向前移动,for循环中i向前移动了,不用管
            }else{
                    sum++;//不等时,次数加1,for循环中i向前移动了,不用管
            }
        }
        return sum;
    }
}

4、平行四边形构造

1、首先需要从n条边长里选出平行四边形的四条边(两两相等);
关于输入n与边长均为正数,所以不考虑小于0的情况,但注意边长的值可能会等于0!!
2、再者就已知平行四边形的四条边,需要计算出平行四边形的面积;
打扰了,这里说的是最大的平行四边形面积,所以长方形面积就是最大的平行四边形面积(因为面积等于底乘以高),计算时直接两边相乘。S=x*y。
3、最终选择出的四条边要使得平行四边形的面积最大,就是找到最长的两个相同边长,当然也有可能为一个正方形,即四条边长是一样的。

public class Main2 {
    public static void main(String[] args) {
    	//输入N
        Scanner ss1 = new Scanner(System.in);
        int N = ss1.nextInt();
		//连续输入N个数,存入数组
        int[] a=new int[N];
        for (int i=0;i<N;i++) {
            a[i] = ss1.nextInt();
        }
		//排序+遍历
        System.out.println(fun(a));

    }
	//排序后找出重复且最大的两个数
    private static int fun(int[] arr) {
        Arrays.sort(arr);
        int i = 0;
        int max = 1;//面积
        //找出出现过两次且最大的两个数
        for (int j = arr.length - 1; j >= 1; j--) {
            if (arr[j] == arr[j - 1]) {
                max = max * arr[j];
                j = j - 1;
                i++;
                if (i == 2) break;
            }
        }
        if (i < 2) {
            return 0;//出现次数为2次的数少于2,不能构成平行四边形
        } else {
            return max;
        }
    }
}
    
#include<iostream>
#include<vector>
using namespace std;
int main()
{
	int n;
	cin>>n;

	vector<int> a(n);
	for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
	//特殊处理
	if(n<4 || n>50000)
		cout<<-1;

	//根据边长个数与边长大小找最合适的边长
	vector<int> count(10,0);
	int x=0,y=0;//设置x和y为长方形的边长
	float r=0;
	for(int i=0;i<n;i++)
	{
		count[a[i]]++;//统计每个边长出现的次数

		if(count[a[i]] >= 2 && count[a[i]]<4 && a[i]>0)// 为长方形时(a[i]>0可以省略,题目已经是输入为正整数)
		{
			if(a[i] >= x)
			{
				y = x;
				x = a[i];
			}
			r = x*y;//面积等于长乘以宽
		}
		else if(count[a[i]] >= 4 && a[i]>0)//为正方形时 
		{
			if(r < a[i]*a[i])
			{
				r = a[i]*a[i];//面积等于边长相乘
			}
		}
		else//否则不符合题意,直接return 0;
		{
			cout<<-1;
			return 0;
		}
	}

	if(r>0)
		cout<<r;
	else
		cout<<-1;
	return 0;
}

5、范围攻击

public static void main(String args[]){
    	Scanner cin = new Scanner(System.in);
    	int n = cin.nextInt();
    	int y = cin.nextInt();
    	int[][] monster = new int[n][2];
    	for (int i = 0; i < n; i++) {
    		int x = cin.nextInt();
    		int hp = cin.nextInt();
			monster[i][0] = x;
			monster[i][1] = hp;
		}
    	// 注意二维数组的重排序需要实现Comparator接口的对应比较方法
    	Arrays.sort(monster,Comparator.comparingInt(p -> p[0]));
    	// 总攻击次数
    	int time = 0;
    	// 遍历每一个怪物
    	for (int i = 0; i < n; i++) {
    		// 若怪物还有血
			while (monster[i][1] > 0) {
				// 灭掉该怪物还需多少刀
				int killTime = monster[i][1];
				// 看看同时还能顺便砍到右边哪些怪
				for (int j = i; j < n; j++) {
					// 满足该条件,则这些怪也能被顺便砍
					if (monster[j][0]-monster[i][0] <= y*2) {
						monster[j][1] -= killTime;
					}
				}
				time += killTime;
			}
		}
    	System.out.println(time);
    }
}

6、股票

public class Main2 {
    public static void main(String args[]){
        Scanner cin = new Scanner(System.in);
        while (cin.hasNext()) {
			int m = cin.nextInt();
			System.out.println(money(m));
		}
    }
    public static int money(int day) {
    	// 当前的天数
		int now = 1;
		// 阶段,现在是连续加1次的阶段,接下来是连续加2次的阶段
		int stage = 1;
		// 当前余额
		int mon = 1;	
		// 当轮到第day天时,跳出并返回余额
		while (now < day) {
			// 开始连续加stage次,若没有加完那么多次,说明日期到头了
			for(int i=0; i<stage && now<day; i++) {
				mon++;
				now++;
			}
			if(now == day) {
				return mon;
			}
			// 加完stage次,以后的stage要加一,即连续多加一次
			stage++;
			// 然后减一次
			mon--;
			now++;
		}
		return mon;
	}
}

7、反转数组,片段反转升序排列

import java.util.*;

public class Main3 {
    public static void main(String args[]){
        Scanner cin = new Scanner(System.in);
        int m;
        int n;
        m = cin.nextInt();
        int[] array = new int[m];
        // 拷贝数组
        int[] copy = new int[m];
        for (int i = 0; i < m; i++) {
        	n = cin.nextInt();
        	array[i] = n;
        	copy[i] = n;
		} 
        // 将拷贝数组排序
        Arrays.sort(copy);
        
        int left = 0;
        int right = m-1;
        // 从左找到不相同的位置
        while (left < m && copy[left] == array[left]) {
			left++;
		}
        // 当越界,说明整个数组是升序,返回no
        if (left >= m ) {
        	System.out.println("no");
        	return;
        }
        // 从右找到不相同的位置
        while (right >= 0 && copy[right] == array[right]) {
        	right--;
        }
        // 当越界,说明整个数组是升序,返回no
        if (right < 0 ) {
			System.out.println("no");
			return;
		}
        // 看中间部分的值,array和copy是否反转相等
        for (int i = left; i <= right; i++) {
        	if (array[i] != copy[right-i+left]) {
				System.out.println("no");
				return;
			}
        } 
        System.out.println("yes");
        return;
    }
}

8、圈地最大面积

public void area(int r){
    if(r <= 1) System.out.println(0);
    int count = 0;
    for(int i = 1;i <= r;i++)
        for(int j = 1;j <= r;j++){
            double distance = Math.sqrt(i * i + j * j);
            if(distance <= r) count++;
        }
    System.out.println(count * 4);
}

9、序列元素各不相同

 public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int n = cin.nextInt();
        int[] arr = new int[n];
        for(int i = 0;i < n; i++){
            arr[i] = cin.nextInt();
        }
        TreeSet<Integer> set = new TreeSet<>((x,y)->(y-x));
        for(int num:arr){
            boolean b = set.add(num);
            while (!b){
                set.remove(num);
                num = num*2;
                b=set.add(num);
            }
        }
        System.out.print("操作后:");
        for (Integer num:set
             ) {
            System.out.print(num+" ");
        }

10、种草

public static void main(String[] args) {
        PriorityQueue<Integer> priorityQueue = new PriorityQueue();
        Scanner cin = new Scanner(System.in);
        int n = cin.nextInt();//小草个数
        int m = cin.nextInt();//药剂数量
        int x = cin.nextInt();//药剂的药效

        for (int i = 0; i < n; i++) {
            int high = cin.nextInt();
            priorityQueue.add(high);
        }
        while (m-->0){
            int low = priorityQueue.peek();
            priorityQueue.remove(low);
            priorityQueue.add(low+x);
        }

        System.out.println("药剂用完后的最矮小草的高度为:"+priorityQueue.peek());

    }

11、射击游戏

剪花
n只花,第i只的高度为h(i)厘米,最适宜生长的高度是w厘米,所以需要修剪。当修剪一只花时,其右边的花就会长高a厘米。
若每天只能修剪一只花,不超过w不需修剪,费用为1元/厘米,总共需要花费多少钱?

最长因子序列
在x,y之间的正整数,其中a是b的因子,b是c的因子… 最长的序列为多长

射击游戏
sha手狙击枪4发子弹,发射完需要w秒填弹。每秒可以开一枪。敌人每秒出现一次,然后消失。n个敌人,第i个敌人的分数是a[i]。每次剩的最后一个子弹可得双倍分,最多可以得多少分?

12、五个吃货在海边忙活了一天,挖了一堆生蚝

13、求一个数的二进制表示中的1位的个数

14、数组中的跳跃最大长度

15、猴子摘桃

16、把数字翻译成字符串

17、乌鸦喝水

18、棋盘问题

19、白球和黑球


版权声明:本文为qq_38663663原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。