zoukankan      html  css  js  c++  java
  • 10.17(山东多校联合模拟赛 day1)

    山东多校联合模拟赛 day1

    题不难

    rect

    【问题描述】

    给出圆周上的 N 个点, 请你计算出以这些点中的任意四个为四个角,能构成多少个矩形。

    点的坐标是这样描述的, 给定一个数组 v[1..N], 假设圆心为(0, 0), 圆的周长 C=∑v[1..N] , 第一个点坐标为(0, C/(2π))。 从第一个点开始, 顺时针沿圆周走 v1 个单位长度,此时坐标为第二个点的坐标,再走 v2 个单位长度,此时为第三个点的坐标,当走完 v1, v2..vi个距离后,为第 i+1 个点的坐标(全过程都是沿圆周顺时针)。 特别的, 走完 v1, v2..vn 个距离后, 就会回到第一个点。

    【输入】

    输入文件名为 rect.in。

    输入共 N+1 行。

    第一行为正整数 N。

    接下来 N 行每行一个正整数。 其中第 i+1 行表示的是 v[i]。

    【输出】

    输出文件名为 rect.out。

    输出共 1 行,一个整数,表示能构成的矩形的个数。

    【输入样例1】

    8
    1
    2
    2
    3
    1
    1
    3
    3
    

    【输出样例1】

    3
    

    【数据范围】

    对于 100%的数据,有 N<=20, V 数组中的所有元素的值<=100。

    【题解】

    由于所有的点在圆上,所以可以处理出这些点能组成多少个直径。最后答案为C(直径数量,2)。由于N特别小,处理就是枚举端点即可。如果N是100万,可以考虑维护两个指针处理直径。

    ancestor

    【问题描述】

    任何一种生物的 DNA 都可以表示为一个由小写英文字母组成的非空字符串。科学家发现,所有的生物都有可能发生变异。所谓变,就是子代的 DNA 串与父代的 DNA 串有差异。每次变异, DNA 串中恰好有一个字符会变成两个任意的字符。一共有 n 种可能的变异。变异 ai->bici 表示字符 ai 有可能变异为两个字符 bici。详细来说,就是删掉一个字符 ai,之后在原来 ai 的位置处,插入 bi, ci 两个字符(注意字符 bi 必须在 ci 的前面)。每种变异都有可能发生任意多次。可以发现,每变异一次, DNA 串的长度会加 1。

    如果有一种生物 a,他的 DNA 串是 s1,另外存在一种生物 b,他的 DNA 串是 s2。如果 s2 可以通过若干次变异变为 s1,那么生物 b 就被叫做生物 a 的祖先。

    现在,给定一种生物,他的 DNA 串是 s。请找出他的一个祖先,且这个祖先的 DNA 串尽量短。

    【输入】

    输入文件 ancestor.in,共 n+2 行。

    第一行包含一个非空字符串 s。

    第二行含有一个整数 n,表示所有可能的变异。

    接下来 n 行,每行描述一种可能的变异,按照 ai->bici 的格式。

    s, ai, bi, ci 仅包含小写英文字母。

    请注意:一种变异可能出现多次。

    【输出】

    输出文件名为 ancestor.out。

    输出只有一行, 一个整数,表示祖先 DNA 串的最短长度。

    【输入样例1】

    ababa
    2
    c->ba
    c->cc
    

    【输出样例1】

    2
    

    【输入样例2】

    ababa
    7
    c->ba
    c->cc
    e->ab
    z->ea
    b->ba
    d->dd
    d->ab
    

    【输出样例2】

    1
    

    【数据范围】

    对于 30%的数据, s 的长度<=5, N <= 3;

    对于 100%的数据, s 的长度<=50, N <= 50

    【题解】

    DP题。设f[l][r][t]代表区间[l,r]是否可以变成一个字母t,那么初始状态为f[i][i][t]=[s[i]==t]。枚举区间的长度和端点,对于一个区间,转移的时候枚举中间点和所有变异即可。

    再设一个fuck[l][r]代表[l,r]合并后的最短长度。根据上面的设置,当(exist)f[l][r][t]=true时,fuck[l][r]=1,否则枚举中间点,fuck[l][r]为两边相加的最小值。

    f1

    【问题描述】

    F1,中文全称为一级方程式锦标赛,是最高级的方程式赛车比赛,现在你作为一名选手参加了一场 F1 的比赛,比较特殊地,本次比赛是在一个 N 个点 M 条边的无向图上举行的。

    起点是 S,终点是 T,每条边长度为 1 公里,赛车每行驶 1 公里耗油 1 个单位,途中共有 k 个加油站, 每经过加油站时,可以把油加满,但你的赛车设计顾问告诉你,油箱容量越大,赛车跑的就越慢。 为了追求最快的速度, 在能顺利到达终点, 不会中途没油的前提下,你希望最小化油箱的容量(注意,虽然油箱变小可能导致路径变长,但我们只关心最小化的油箱)。

    【输入】

    输入文件 f1.in。

    第一行一个正整数 T 表示测试数据组数, 每组数据格式如下:

    第一行三个整数, N,M,K,表示无向图的点数,边数,加油站数。

    第二行 K 个正整数 i1,i2..ik 表示这些点上有加油站(可能重复,保证至少一个加油站在S 点)。

    接下来 M 行,每行两个正整数 Bi,Ei 表示有一条连接(Bi,Ei)的双向边(可能有重边和自环)。

    最后一行两个正整数 S,T 表示起点、终点。

    【输出】

    输出文件名为 f1.out。

    对于每组数据, 如果没法到达终点,输出-1,否则输出最小化的油箱容量。

    【输入样例】

    2
    6 6 3
    1 3 6
    1 2
    2 3
    4 2
    5 6
    4 5
    3 4
    1 6
    7 10 3
    1 3 4
    1 2
    4 2
    7 5
    4 5
    7 1
    2 5
    7 2
    3 7
    3 2
    5 1
    4 6
    

    【输出样例】

    3
    -1
    

    【数据范围】

    对于 30%的数据, N<=200,M<=2000。

    对于 60%的数据, N<=1000,M<=10000。

    对于 100%的数据, 1<=K,S,T<=N<=100000,1<=M<=150000,1<=T<=5。

    【题解】

    由于答案是单调的(如果一个油箱容量合法,那么所有比这个容量大的油箱都合法),那么二分答案把题目转化为判定性问题。从起点开始,设d[i]为某点的油箱的最大值,跑最短路即可。注意这里必须使用spfa:下面的图如果用dijkstra就会出问题

                    [T]
                     |
                     |
                    [.]
                     |
                     |
                     |
    [S] --- [.] --- [.] --- [O]
    

    ASCII艺术。。。如图S是起点T是终点O是加油站,那么当油箱容量为3的时候,需要在加油站中转一下,这样我们重复更新了拐弯处的点的油箱信息。而dijkstra,bfs等算法是不允许重复更新某个节点的,而spfa允许,所以需要使用spfa。关于SPFA他其实没死,只是我们遇到最短路优先考虑dij更好。

    ps昨天的题我自己厚颜无耻地从某网站扒的就不放了

  • 相关阅读:
    Linux系统挂载存储只读改成读写
    Linux kernel调试方法
    Linux设备树文件结构与解析深度分析
    #undef常用法
    Linux驱动中的platform总线分析
    在根文件系统中查看设备树(有助于调试)
    友元及操作符重载
    STM32 FLASH 擦除(以及防止误擦除程序代码)、写入
    C++学习笔记49:栈
    C++学习笔记48:链表的基本操作
  • 原文地址:https://www.cnblogs.com/oier/p/9803837.html
Copyright © 2011-2022 走看看