暑期培训7日游解题思路(day1~day3)
暑期培训7日游解题思路(day1~day3)
day1
第一天,王聿中老师出的题目比较简单,T1很水,T2是个简单的DP,T3还是有一点意思的。在网格图中删掉若干条边,使得所有格子都联通,求删掉的边的长度和最小为多少。很容易发现这是一个最小生成树问题,但点和边数量非常大,不可能完成一般的建图,然后发现这是网格图,同一行的竖边都相等,同一列的横边也都相等。克鲁斯卡尔每次找最短的边e(u,v),若u,v在不同的连通块,则取该边。所以在本题中如果要取某一条边,与它长度相等的边如果可以去就要取,因此每一次可以打通一列或一行,这样只要记录下有几行几列已经被打通,就可以统计出答案。一个对克鲁斯卡尔的变形,也比较容易。1个多小时就把比赛AK了,一共10人AK,不过之后的比赛再也看不到300了。
day2
题目也不算难。
T1依然是水题,想怎么做就怎么做。
T2是一道不错的题目,题目大意:有4组数,每组n个,每组个选一个数组成一个四元组,使得四个数相乘模p等于1,保证p是质数。n<=1000.
最暴力的方法是n^4次枚举,显然不行。这个规模应该要O(n^2)或O(n^2 log n).
也就是说只能枚举两个。于是可以先枚举前面两个,把它们记下来,排序,然后枚举后面两个,求乘积的逆元,在那个有序序列中查询。这样子时间复杂度O(n^2 logn).
这种方法叫做Meeting in the middle,是一个重要的优化方法。
T3是一道有趣的题目,题目大意:一条长度固定的贪吃蛇(l<=8),在n*m的网格图上(n,m<=20),网格图上有k个障碍物(保证l+k<=n*m),任意时刻蛇不能有两节在同一个格子上。给定蛇的每一节的初始位子,问蛇头到目标位置最少要多少时间。
看到数据比较小,大胆地写了一个玄学搜索,加了一些靠谱的小优化,程序跑得飞快,自己出的大数据可以在0.01秒内跑完,以为稳了,打了接近两个小时的扫雷……结果TLE了……50分,还好。
不要玄学这种东西,我们来看正解。蛇当然是连续的(不然怎么活),在网格图中只有4种方向,所以蛇头的位置和每一节弯曲的方向(状压)就可以确定所有的状态。20*20*4^7次,可以接受。写一个宽搜,用一个数组记录每一个状态是否到过,于是一个时间复杂度稳定的算法就出现了。其实还可以优化,但不是很有必要,除了第二个方向,后面每一节都只有三个可能的方向,所以只要20*20*4*3^6个状态。
day3
T1是个模拟题,跳过。
T2比前面两个T2要难得多。题目大意:有一个n*m的网格,每一个格子是“.”或“*”,求一个由“.”的格子组成的矩形周长最大是多少。这道题似乎与这道题差不多(好像是一模一样……)
房屋建造
题目描述
小明是一位有名的建筑师。他买了一块地来建造房子。不幸的是,这块地的地势是会变化的,它有一个可变仰角。
土地的形状是一个长方形,N米宽M米长。它可以被分为N*M个方块(见下图)。小明的房子也是一个长方形,房子的边与土地的边都是平行的。为了房子不会倒塌,小明建房子的土地必须都是同一个地势的。
上图中小明建立房子的其中两种是红色和蓝色覆盖的区域。计算小明可以有多少种方式来建立他的房子。
输入
输入第一行包括两个整数N和M(1≤N,M≤1000)。
接下来的N行中每行包括M个整数ai,j(1≤ai,j≤10^9),表示每一块土地的地势高度。
输出
输出一个整数,表示小明最多有多少种建立房子的方式。
样例输入
5 3
2 2 2
2 2 1
1 1 1
2 1 2
1 2 1
4 3
1 1 1
1 1 1
2 2 2
2 2 2
样例输出
27
36
提示
【数据范围】
20%的测试数据中,N,M≤50。
60%的测试数据中,N,M≤500。
解题思路:预处理出以每一个格子为底的最长的连续“.”的长度a[i][j]。然后枚举每一行,用单调队列预处理出每一个点向左、向右的最长的距离l[j]、r[j],使得距任意离内的a[i][k]>=a[i][j],然后枚举每一个点ans=max(ans,(l[j]+r[j]+1+a[i][j])*2)