zoukankan      html  css  js  c++  java
  • 常州培训 day1 解题报告

    第一题:(骗分容易,AC难。)

    题目大意:

    给出一个字符串,找出满足条件A的区间的个数。A:字符A,B,C的出现次数相同。 都出现0次也算,区间的长度可以是0(就是只有一个数).
    30% |S| ≤ 100 。
    70% |S| ≤ 1000 。
    100% 1 ≤ |S| ≤ 1000000 。

    解题过程:

    1.考场上想不出AC算法,但是70分是很好拿的,最先想到先求出A,B,C出现次数的前缀和,枚举区间的两个端点,O(1)时间判断,枚举O(n^2)。

    2.一看后面的题目都不是很好写,就先来优化一下这题,由于只有A,B,C是有用的,所以把其他字母拿掉,并把每个有效字母(A,B,C)后面的无效字母的个数保存下来,然后方法和前面一样,加些细节处理,这样就可以把区间的长度大大缩短。但是实际证明,这样是在做无用功,还是只有70分,还不如直接朴素算法省力。

    3.AC算法:假设区间[i,j]符合要求,那么SUMA[j]-SUMA[i-1]=SUMB[j]-SUMB[i-1]=SUMC[j]-SUMC[j-1],变形一下得到

    SUMA[j]-SUMB[j]=SUMA[i-1]-SUMB[i-1];

    SUMB[j]-SUMC[j]=SUMB[i-1]-SUMC[i-1];

    也就是说 如果区间[i,j]符合要求,必须满足j和i-1的  A-B的个数相等,j和i-1的B-C的个数相等。

    那么只要把一个点 描述成一个二元组{SUMA-SUMB,SUMB-SUMC}, 找到一个和它完全相等的,就可以当成一个符合要求的区间的两个端点。

    那么只要把所有二元组排个序,以SUMA-SUMB为第一关键字,SUMB-SUMC为第二关键字。如果有连续的n个相等的二元组,那么就表示有n*(n-1)/2个合法区间,累加到答案里就好。

    但是这样还不完善,这样是没法找出 区间[1,R]的(一开始没考虑到,想了半天才明白,因为如果[i,j]合法,我们找到的是i-1和j,而0并没有算进去)。 所以一开始要虚拟一个二元组{0,0}再排序。

    第二题:(较难)

    题目大意:

    给出一个N个点M条边的无环图DAG,点的编号是1—N,求出满足条件A的路径的数量。A:路径上所有点的编号的乘积是一个完全平方数。N<=90,M<=3000.

    解题过程:
    1.一开始想到的自然是搜索,保存当前乘积的分解质因数结果(只要保存每个质因数个数的奇偶性,01表示即可),能拿30分。之后想到如果当前乘积是一个完全平方数, 那么继续走,要想乘积为完全平方数,那么之后走的点的编号乘积必定也是完全平方数。 那么只要反向存边做一个拓扑排序,保存以点i为起点的满足条件的路径数F[i],当搜索到一个节点node且乘积是完全平方数的时候,就不要继续搜索了,加上它所有后继点j的F[j]即可;另外N<=90,那么如果搜到当前乘积有大于等于47的质因数,那么必定不会是完全平方数了,直接终止搜索。。 丧心病狂地做了那么多,结果和爆搜一样,还是30分,只能说数据跨度有点大。。。

    2.正解:状态压缩DP,F[node][s]表示以node为终点,且乘积的分解质因数结果的奇偶性情况为s的最多路径数。质因数最大为43,一共14个,所以s最大只有2^14-1。

    转移方程:F[node][s]=sum(F[k][s xor j]),k为s的前驱,j为node分解质因数的结果。

    复杂度分析:首先N*2^14个状态,对于每条边,都用来转移了2^14*M次,复杂度就是(2^14*(N+M));

    转移的时候可以用记忆化搜索,也可以做一次拓扑排序,按照拓扑序来求F[node][s],为的是在求node时保证node的前驱已经求过。

     

    第三题:(想到算法就很简单)

    题目大意:

    给出N个点M条边的无向图和边的权值,给出K对点,求出最小的D,使得删去所有权值小于等于D的边后,K对点不能互相到达。若不可能,输出-1.
    30% N ≤ 100,M ≤ 300,K ≤ 100, ≤ 100 。 Xi<=100
    60% N ≤ 1000,M ≤ 3000,K ≤ 1000 。
    100% N ≤ 100000,M ≤ 300000,K ≤ 100000,  Xi≤10^9 。

    解题过程:

    1.首先看无解的情况,(考试时想了半天没想到),就是 给出的点对 是两个相同的点,感觉这有点无聊了。

    2.AC算法考试时没想到,做了个改造的SPFA,复杂度O(NM):先用前向星把每个点需要到达的点保存下来,从每个点出发做一次SPFA,求出到达 要到的点的路径中最大边的最小值即可,可以拿到60分(没考虑无解,55分);

    3.AC算法:二分D,把所有权值小于等于D的边暂时删去,然后用并查集判断点对能否连通。(讲明白了好简单,10分钟写完的。)

     

    成绩不是很理想,3个题目加起来才120分,和其他人的差距还是挺大的。以后还是要努力。

  • 相关阅读:
    Python——thread
    Python——dummy_thread( _dummy_thread in Python 3.+)
    Python——pyiso8601
    Python——os(一)进程参数
    Python——eventlet.hubs
    Python——eventlet.backdoor
    Python——eventlet.greenthread
    解决zabbix可用性为灰色状态
    实时查看docker容器日志
    docker pull 报错Get https://xxx.xxx.xxx.xxx:5000/v1/_ping: http: server gave HTTP response
  • 原文地址:https://www.cnblogs.com/vb4896/p/3907087.html
Copyright © 2011-2022 走看看