A
题意:平面上有n个点(n<=100000),给你一个p(20<=p<=100) 判断是否存在一条直线至少过[np/100](向上取整)个点,时限20s,多组数据
分析:概率算法
最直接的想法是枚举任意两个点算出这条直线经过多少点,这样至少也是O(n^2)(当然肯定不止),TLE
注意p>=20,假设结果存在,那么这条直线要经过至少n/5个点
那么一次枚举两个点,成功的概率是1/5*1/5=1/25
也就是说如果结果存在,那么一次枚举枚举不到的概率是24/25
如果枚举n次,一直都枚举不到的概率是(24/25)^n
当n比较大的时候,这种枚举不到的概率就很小
所以根据相应时限可以得到一个n的值,进行枚举,如果找到了那么就是possible,如果没找到就可以认为是impossible,我取的n是250
注意特判n=1
B
题意:f(0)="R",f(i)=~f(i-1)(R变成B,B变成R)+f(i-1),询问第Y次的字符串第P位是R还是B
分析:分治
每次可以根据当前位置和中间位置作比较,去左边还是右边,注意的是每次递归都要有一个d来表示当前层第一位是R还是B,如果进入左边则d不变,如果进入右边则d^1
C
题意:n*n的矩阵(n<=200),找到一个最大的k,使得存在一个k*k的矩阵,每一行每一列都是回文串
分析:预处理
h[k][i][j]表示第k行,第i位到第j位是否是回文串,这个可以用区间dp求出,h[k][i][j]|=h[k][i+1][j-1]&&s[k][i]==s[k][j],注意初始化的时候要考虑两个相邻的相同字母
l[k][i][j]同理表示列的
现在可以想到如果枚举(i,j),再枚举个k,那么还需要n的时间check,所以时间复杂度是O(n^4)->TLE,还需要预处理
f[i][j][k]表示s[i][j]s[i][j+1]s[i][j+2]......s[i][j+k-1]这段串一直向下扩展最多能扩展多少行(也就是保证每行的i...j+k-1都是回文串)
同理g[i][j][k]是表示列的情况
那么再枚举(i,j)和k,就可以通过O(1)的时间判断k是否可行了,即判断f[i][j][k]和g[i][j][k]是否都>=k
O(n^3)
D
题意:将一个数分解质因数,将不同的质因子加起来得到一个新数,不断操作直到成为一个素数,操作的次数就称为原始数的操作次数;给出A,B,K(均<=1000000),询问[A,B]内操作次数为K的数有多少(有P<=100000组查询)
分析:筛+vector
首先可以根据素数筛很容得到每个数的不同质因子的和s[i]
f[i]表示操作次数,那么f[i]=f[sum[i]]+1 (sum[i]一定小于i)
然后就是查询的问题
易得操作次数肯定不会太大(实际上最多不会超过13)
那么就可以根据操作次数,把操作次数相同的数从小打到放进vector中
对于每个查询[A,B],只要在K对应的那个vector中二分查找就行了
E
题意:T<=100组数据,每组数据给出n个数,你每次可以任选两个数,将其中一个+1,另一个-1,问经过若干次操作,最多能有多少个数相等
分析:思维题
选择一个数作为辅助数,那么可以将其它所有数的大小任意调,当然可以调到都相等,所以答案至少是n-1
答案能否为n呢?如果所有数的和能被n整除,那么就是n了
F
题意:一道计算几何,留坑