计算三个矩形相交的面积

输入数据:左上角x坐标 y坐标 矩形宽 矩形高

思路就是
写一个矩形类, 类里写和另一个矩形比较重叠的方法, 这个方法返回的是重叠的矩形 ,
类里要有坐标信息字段,判断自身是不是一个矩形,然后类里写一个方法计算自身面积

  1. array = []#一个空数组
  2. for i in range(3):#三个矩形 插入三次
  3. array.append([int(n) for n in input().split()])
  4. #input()输入进来强制字符串类型,split()切片得到字符串列表,也可以理解成一维数组
  5. #for 方法把列表中的元素一个单独取出来,取出来的同时使用int()方法给转成整形
  6. #最后用[]把内容框起来成为一个一维数组插入到array数组里
  7. class Rec:#矩形类
  8. @classmethod #实例化对象用 可以用来调用类的属性,类的方法,实例化对象等。
  9. def initByWH(cls, x, y, w, h):#cls是这个类本身 左上x 左上y
  10. x2 = x + w
  11. y2 = y - h
  12. return cls(x, y, x2, y2)#返回左上x 左上y 右下x 右下y
  13. def __init__(self, x1, y1, x2, y2):#初始化方法
  14. self.x1 = x1
  15. self.y1 = y1
  16. self.x2 = x2
  17. self.y2 = y2
  18. self.w = x2 - x1
  19. self.h = y1 - y2
  20. def getSize(self):#计算面积
  21. return self.w * self.h
  22. def valid(self):#认可函数,如果左上x小于等于右下x 且左上y大于等于右下y
  23. return self.x1 <= self.x2 and self.y1 >= self.y2
  24. def getOverlap(self, rec):#比较后,获取重叠矩形的四个点
  25. resultX1 = rec.x1 if rec.x1 > self.x1 else self.x1#左上x选 x值大的那个
  26. resultX2 = rec.x2 if rec.x2 < self.x2 else self.x2#右下x选 x值小的那个
  27. resultY1 = rec.y1 if rec.y1 < self.y1 else self.y1#左上y选 y值小的那个
  28. resultY2 = rec.y2 if rec.y2 > self.y2 else self.y2#右下y选 y值大的那个
  29. result = Rec(resultX1, resultY1, resultX2, resultY2)
  30. if result.valid():#如果新的矩形四个点符合逻辑就返回参数,不符合return None程序结束
  31. return result
  32. return None
  33. rec1 = Rec.initByWH(array[0][0],array[0][1],array[0][2],array[0][3])#实例化三个矩形
  34. rec2 = Rec.initByWH(array[1][0],array[1][1],array[1][2],array[1][3])
  35. rec3 = Rec.initByWH(array[2][0],array[2][1],array[2][2],array[2][3])
  36. temp = rec1.getOverlap(rec2)#获取第一个和第二个矩形得到的重叠的矩形
  37. result = temp.getOverlap(rec3)#把得到的重叠矩形和第三个矩形继续重叠
  38. print(result.getSize())#计算最后的重叠面积

实现金字塔输出 奇数行正序输出 偶数行逆序输出 不足四位需要用*补位

具体思路:
首先是一个外循环-控制行数,并准备一个空列表记录该行要输出的内容
接着内循环,输出该行的相应个数的数据,从第一行开始,是第几行就输出几个数据,利用一个全局变量s,记录目前输出的数据,需要输出就自增1,并且如果s不足4位要执行补位,为了,每生成完一个数就插入到空列表里
做完该行要输出的所有数据后,为了实现金字塔输出需要在最前面插入空格,空格的数量由目标行数减去当前行数决定
最后根据行数是奇数还是偶数决定列表是正序输出还是逆序输出

  1. count = int(input())
  2. sum = 0
  3. for i in range(1,count+1):#i的意义是该行的输出个数
  4. list = []
  5. for j in range(i): #这行输出多少个
  6. sum += 1 #sum是输出的数字
  7. s = str(sum).ljust(4,"*") #处理不足4位补位
  8. #ljust() 方法返回一个原字符串左对齐,并使用空格填充至指定长度的新字符
  9. s = s
  10. list.append(s) #添加到list
  11. if i != count: #不是最后一行
  12. for time in range(count-i): #输出前的空格个数
  13. print(' ',end='') #end='' 为不换行输出
  14. if i%2==1: #奇数行正序输出
  15. for s in list:
  16. print(s,end = ' ')
  17. else: #偶数行逆序输出
  18. for s in list[::-1]:
  19. print(s,end = ' ')
  20. print()#换行

贪吃蛇

思路:
首先获取操作,然后生成地图,然后往地图上放东西,然后才开始找起点,遍历操作,计算结果 判断结果

  1. package Huawei;
  2. import java.util.LinkedList;
  3. import java.util.Scanner;
  4. /**
  5. * @description:
  6. * @author: Polaris
  7. * @date: 2022/3/31 19:53
  8. */
  9. public class no9 {
  10. static char[][] arr =null;#二维数组
  11. public static void main(String[] args) {#主函数
  12. Scanner sc = new Scanner(System.in)
  13. #Scanner sc = new Scanner(System.in);此句 表示从控制台获取数据,
  14. #sc.hasNext() 表示你是否有输入数据,
  15. #while语句块 表示当你输入数据的时候,就执行输出sc.next()(输出内容)
  16. #所以只要你输入数据了,它就可以执行,
  17. #具体的输入:
  18. #GGG #G上U下D左L右 G当前方向前进
  19. #33 #行 列
  20. #FFF #H起始位置,F食物,E为空
  21. #FFH
  22. #EFE
  23. #结局向左走了两步,吃到两个食物 第三步撞墙了,最后的长度为3
  24. while (sc.hasNext()){
  25. char[] ch = sc.nextLine().replaceAll(" ","").toCharArray();#ch是操作
  26. int N = sc.nextInt();#NM生成地图
  27. int M = sc.nextInt();
  28. arr = new char[N][M];
  29. for(int i =0;i<arr.length;i++){#往地图上塞东西
  30. for(int j = 0;j<arr[i].length;j++){
  31. arr[i][j] = sc.next().charAt(0);
  32. }
  33. }
  34. fun(arr,ch);#fun方法先是找到蛇的起点
  35. }
  36. }
  37. static void fun(char[][] arr,char[] ch){#fun方法先遍历地图找到蛇的起点
  38. LinkedList<int[]> snake = new LinkedList<>();?
  39. int[] start = new int[2];
  40. //先遍历地图找到蛇的起点
  41. for(int i=0;i<arr.length;i++){
  42. for(int j=0;j<arr[i].length;j++){
  43. if(arr[i][j] == 'H'){
  44. start[0]=i;
  45. start[1]=j;
  46. break;
  47. }
  48. }
  49. }
  50. //起点入队
  51. snake.add(start);
  52. //遍历操作列表
  53. for(int i =0;i<ch.length;i++){
  54. int flag = 0;
  55. if(ch[i]=='U'){
  56. flag=1;#flag只是用来区分不同操作的
  57. continue;
  58. }else if(ch[i]=='D'){
  59. flag=-1;
  60. continue;
  61. }else if(ch[i]=='L'){
  62. flag=-2;
  63. continue;
  64. }else if(ch[i]=='R'){
  65. flag=2;
  66. continue;
  67. }else if(ch[i]=='G'){
  68. switch (flag){
  69. case 1:
  70. start[0]++;#start 起点位置
  71. break;
  72. case -1:
  73. start[0]--;
  74. break;
  75. case 2:
  76. start[1]++;
  77. break;
  78. case -2:
  79. start[1]--;
  80. break;
  81. }
  82. if(isEnd(snake,start)){#根据flag就是对应的操作,来移动蛇的头,就是start
  83. #isEnd类判断是否结束
  84. break;
  85. }
  86. //吃到,只加不减#然后判断是撞墙了终结了 还是吃到东西了,还是没吃也没死
  87. #吃到就只加头到那个位置,没吃到还要把尾巴减一个
  88. if(arr[start[0]][start[1]]=='F'){
  89. snake.addFirst(start);
  90. }else{
  91. //没吃到,加头去尾
  92. snake.addFirst(start);#snake是个二维数组的list
  93. snake.removeLast();
  94. }
  95. }
  96. }
  97. System.out.println(snake.size());
  98. }
  99. static boolean isEnd(LinkedList<int[]> list,int[] a){#判断结束的方法,就是判断撞墙和撞自己
  100. //撞墙了
  101. if(a[0]>=arr.length||a[1]>=arr[0].length)
  102. return true;
  103. //撞到自己了
  104. for(int[] i:list){
  105. if(i[0]==a[0]&&i[1]==a[1])
  106. return true;
  107. }
  108. return false;
  109. }
  110. }

8皇后

具体的思路:

步骤1

第一个皇后先放在第一行第一列


步骤2

第二个皇后放在第二行第一列,然后判断是否与约束条件冲突,如果冲突,继续放在第二列,第三列直到找到一个合适的位置

步骤3

继续第三个皇后,同样是第一列,第二列直到第八个皇后也能放在一个不冲突的位置,算是找到一个正确解

步骤4

然后就开始回溯,一直到把第一个皇后放在第一列的所有正确解全都得到

步骤5

然后回头继续第把第一个皇后放在第二列,循环执行一到四,四个步骤

每次为下一个皇后,寻找合适的位置,就是试探。每次试探不到合理的位置,回头去改变前一个皇后的位置,就是回溯;排除没意义的试探,就是剪枝。上诉的解题过程,就是一个回溯法的思路

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. __author__ = 'C2TR'
  4. def conflict(state, nextColumn):
  5. """
  6. 判断下一行皇后位置是否与之前皇后的位置冲突
  7. 因为坐标是从0开始的,所以state的长度代表了下一行的行坐标
  8. :param state:(7,4,6,0,2) 标记每行皇后所在的位置 (0,7)一行八列 (2,4) (3,6) (4,0) (5,2)
  9. :param nextColumn:下一行的列坐标
  10. :return:
  11. """
  12. nextRow = rows = len(state) # 5----下一行 = 行数 =state的长度
  13. for row in range(rows): # 0,1,2,3,4
  14. # 获取当前行的列
  15. column = state[row]
  16. """
  17. 如何判断是否冲突:
  18. 1. 如果列的差值为0,说明两皇后在同一列
  19. 2. 如果列的差值等于行的差值,说明两皇后在对角线上
  20. """
  21. if abs(column - nextColumn) in [0, nextRow - row]:
  22. return True
  23. return False
  24. # 采用生成器的方式来产生每一个皇后的位置,并用递归来实现下一个皇后的位置
  25. def queens(num, state=()):#采用生成器的方式来产生每一个皇后的位置,并用递归思想实现回溯法计算出每一种结果的皇后的位置
  26. """
  27. 基于递归采用回溯算法,算出每一种结果
  28. :param num: 皇后的数量 8
  29. :param state: 列坐标。初始为空。参数为元组不为列表,因为参数只能为不可变数据类型
  30. :return:
  31. """
  32. # 每一行的列坐标都是从0:7的
  33. # 0,1,2,3,4,5,6,7
  34. for pos in range(num):#----循环8
  35. # 默认state为空。长度为0,但是是不冲突的
  36. # 判断是否冲突,state为空时不冲突
  37. if not conflict(state, pos): # 回溯法的体现----如果位置冲突判断函数返回值为false
  38. # 如果state的长度为7,即到达了倒数第二行,也就是前7行皇后都已经找到了位置,最后一行又没有冲突,返回最后一行的列坐标
  39. if len(state) == num - 1:#
  40. # 最后一行的(pos,)=最后一行的result,然后再递归回去求倒数第二行的result
  41. yield (pos,)
  42. else:
  43. for result in queens(num, state + (pos,)):
  44. """
  45. 递归实现求state:
  46. 1. 向下递归
  47. 第一次(行): pos=0,刚开始不会进入if len(state) == num - 1,进入执行else,会执行queens(num, state + (pos, )),
  48. 第二次(行): 进入else,再调用queens(num, state + (pos, )),递归执行queens(num, state + (pos,) + (pos,))
  49. 第三次(行): 进入else,再调用queens(num, state + (pos,) + (pos,),递归执行queens(num, state + (pos,) + (pos,) + (pos,))
  50. ...
  51. 第七次(行): 执行和上面的一样,不过此时state的长度为7
  52. 第八次(行): 执行f len(state) == num - 1:求出最后一行的列坐标(pos,)
  53. 2.向上递归
  54. 求出第八行的列坐标,就可以求出第七行的(pos,),返回的是第七行和第八行的列坐标((pos,) + result)
  55. 根据下一行的结果依次求出上一行的结果;
  56. ....
  57. 最后求出第一行的列坐标,返回整体结果
  58. """
  59. yield (pos,) + result#生成器,编写当前次数和
  60. def prettyprint(solution):#友好展示棋盘,画出每一种结果的皇后的位置
  61. """
  62. 进行友好展示:为了至关表现棋盘,用X表示皇后的位置
  63. :param solution:
  64. :return:
  65. """
  66. def line(pos, length=len(solution)):
  67. return '.' * (pos) + 'X' + '.' * (length - pos -1)
  68. for pos in solution:
  69. print(line(pos))
  70. if __name__ == '__main__':
  71. solutions = queens(8)
  72. for index, solution in enumerate(solutions):
  73. print('第%d种解决方案:' %(index + 1), solution )
  74. prettyprint(solution)
  75. print('*' * 50)