• 2月28-第五次机试课记录


    暴力枚举

    • 多次使用vis记得清空

    思路与总结

    • 二分可以优化很多

    • 使用dfs进行暴力搜索要知道两次递归的关系,以及递归一次的时候进行的操作,合理的设置参数来达到某些目的

    • 要能够识别暴力搜索,是有些东西看起来有规律,但是实际上不用讨论规律,直接暴力就能够实现,这种做法往往会被忽略

    • 暴力不代表蛮力,也有优化的地方,有时候要防止枚举重复的

      • 有的时候需要考虑换一种枚举方式暴力反而更简单,更容易进行枚举
      • 暴力也可以通过设置合适的顺序来减少枚举的次数
    • 二进制枚举的几个技巧

      //枚举0-2^n - 1
      int len;
      for(int i = 0; i <(1 << len); i ++){
      	//1<<len 即为 2^n
      }
      
      //取每一位为1进行对于操作
      for(int i = 0; i < len; i ++){
      	if(num & (1 < i)){//num为长度为len的数字,1<i进行移位操作,然后使用&就可以获得对应位的二进制了
      		
      	}
      }
      
      

    作业

    • 1108

      • 打表预处理

      • 使用unique优化结果集合

      • 二分法查找顺序集合

        sort(arr, arr + n);
        int size = unique(arr, arr + n) - arr;//unique返回的是排序后多余的下标
        //如 1 2 2 3 4 4 => 1 2 3 2 4 会返回指向第二个2的指针,因此相剪就会变成排序后的长度,再重新利用arr就可以使用去重后的数列
        
    • 1063

      • 埃式打表法求素数,然后判断回文

      • 利用预处理前缀和来快速查找区间的个数

        //打表法求素数
        bool p[N];//false为素数
        void init(){
        	memset(p, 0, sizeof(p));
        	p[1] = [1];//1不是素数
        	for(int i = 2; i < N; i ++){
                if(! p[i]){
        			for(long long j = 1ll * i * i; j < N; j += i){//1.使用longlong,2.递增是+i,不是+1
        				p[j] = true;
        			}
        		}
        	}
        }
        
        //使用前缀和
        int pre[N];
        for(int i = 1; i < N; i ++){
        	if(! p[i] && check(i))
        		sum[i] = sum[i - 1] + 1;
        	else
        		sum[i] = sum[i - 1];
        }
        

    题号

    • PIPIOJ 1130: 奇偶交错排列

    • PIPIOJ 1133: 棋盘问题

    • PIPIOJ 1138: N皇后问题

    • PIPIOJ 1102: PIPI学加法

    • PIPIOJ 1049: PIPI的按钮Ⅰ

    • PIPIOJ 1066: 竖式问题

    • PIPIOJ 1322: 同心共筑中国梦

    • PIPIOJ 1084: 最长公共子序列Ⅱ

    • PIPIOJ 1168: PIPI的方格

    分析

    • 1130
      • 预处理出所有的和,然后使用二分进行查找
    • 1133
      • 这里对枚举有进行优化,为了防止枚举重复的,可以在参数上设置的更加有技巧,这题我参数设置的是选中一个点后,之后枚举只会枚举后面的点,其实更好的是用行来进行操作
    • 1138
      • 很经典的n皇后问题,只是这里vis数组可以扩展到主副对角线
    • 1102
      • 有个去重的技巧,就是在dfs回溯的时候,去除掉相同的数字,防止重复枚举
    • 1049
      • 其次我一开始想的是两层dfs,这样想不太对,因为针对ans答案输出数组来说,两层dfs都是对这个进行操作,那么应该理解成为一层才对,通过设置参数start,来限制枚举开始的起点,从而让dfs有不同的意义
    • 1084
      • 求最长公共子序列,没有想出来,这里给出答案是使用二进制进行模拟,暴力枚举出所有的子序列,使用hashmap保存后,再之后的字符,每次枚举子序列,看看map查询的到么,如果查到了就保存到临时map,之后使用临时map去更新hashmap,来使得每次求出的子序列得到更新,逐渐缩短
      • 对于多个可能的结果,需要去字典序最小但是又要长度最长,就在最后一次循环中,对hashmap中的子序列进行长度判断,如果长度相同进行字典序判断
      • 环状字符处理的技巧,s+=s;扩展成为双倍
    • 1168
      • 如果直接暴力枚举方阵的状态,不合适,考虑到第一行确定,而剩下的就会确定,因此可以直接使用二进制枚举第一行,然后对第一行进行判断是否合题意(要注意的是最后一行还要判断一次,因为之前的循环只是生成最后一行,最后一行的合法性需要额外拿出来判断)
  • 相关阅读:
    一些基本数据类型问题
    File创建
    zip解压文件java
    Arrays 的copyOf()
    浏览器客户端-自定义服务端
    TCP并发复制上传文件
    TCP传输过程复制文件
    TCP通讯
    TCP通讯
    css3 animation
  • 原文地址:https://www.cnblogs.com/faberry/p/12380425.html
Copyright © 2020-2023  润新知