暑假集训D16 2023.8.10 补题 -组队赛

D.Dividing DNA

你在蛋白质中心担任数据分析师,现在有一条全新的 \(DNA\) 链以及一个 \(DNA\) 链数据库,你需要对这条 \(DNA\) 链分成若干个小串,使得分成的 \(DNA\)均不满足数据库中存储的 \(DNA\) 链的子串.输出最多可能有多少个子串不在数据库中.

你与数据库交互的方式为
"\(\ ?\ i\ j\)" ,表示向数据库询问字符串下标从 \(i\)\(j-1\) 这段子串是否已存在.
数据库会对你的询问回复 "absent" or "present".
如果你已确定最多子串的数量,输出 "! x" ,表示最多有 \(x\) 个子串不在数据库中.

\(\operatorname{Solution}\)

不看题解真没想到这题这么简单.

首先这题要求所有子串都要用上,这是一个关键信息.设想我们从开头一直往后询问,如果一直是 present ,也就是说明这小段串是数据库中某段 \(DNA\) 链的子串,那么即使再分,由于这段串本来就已经在数据库中的某串的子串,那么分出来的小串肯定也是数据库中某串的子串.那么只能继续往后添加.这时可能会问:为什么不能把这段串从中间断开,然后与后面的组合?

不可以把这段串从某处断开,因为如果断开,前面那段小串是已经 present ,就不符合题目要求的所有分出的子串都不在数据库中的 \(DNA\) 链的子串的要求.

虽然子串从一处断开,然后与后面位置组合,可能会组合出新的不在数据库中的串.比如 \(CTAG\) ,库中有 \(CT\),\(AG\) ,虽然分成 \(C\), \(TA\) ,\(G\) ,会有 \(TA\) 是满足要求的,但是 \(C\)\(G\) 都是库中的某个串的子串,是不合法的.

那么应该从开头一直往后加脱氧核糖核苷酸,直到 absent,说明这段串不是数据库中任意一个字符串的子串,满足要求,那么答案+1,然后从下一个位置重新开始询问.

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	cin>>n;
	int pre = 0;
	int res = 0;
	
	for(int i = 1;i<=n;i++)
	{
		string t;
		fflush(stdout);
		cout<<"? "<<pre<<" "<<i<<endl<<endl;
		cin>>t;
		if(t=="absent")
		{
			pre = i ;
			res++;
		}
	}
	cout<<"! "<<res<<endl;
	return 0;
}

时间复杂度 \(\operatorname{O}(n)\)

C.Crashing Competition Computer

你需要在一台老旧的计算机上打 \(c\) 个英文字符('a'-'z'),每打一个字符需要消耗 \(1\) 单位时间,并且有 \(p\) 的概率导致计算机崩溃.你可以对打完的字符进行保存,花费 \(t\) 单位时间,如果计算机崩溃后需要消耗 \(r\) 单位时间重启,并且你需要从你上次保存的位置重新打字符.问打完这 \(c\) 个字符的最小期望时间是多少?

\(\operatorname{Solution}\)

\(cost[x]\) 为连续打 \(x\) 个字符且不保存的期望花费时间,那么

\[cost[x] = (cost[x-1]+1)+p\times cost[t]+(1-p)\times 0 \]

\(dp[i]\) 表示打前 \(i\) 个字符的花费的最小期望时间.注意 \(dp[i]\) 在打完前 \(i\) 个字符后并不保存,因为显然最后一个字符不保存所花费的时间一定比保存所花费的时间更少. \(dp[i]\leq cost[i]\)

我们可以枚举前 \(i\) 个字符中在第 \(1\sim i-1\) 中的哪个字符打完后按保存更优.
\(dp[i] =\operatorname{min} (dp[k] + t + cost[i-k] ),k \in [1,i-1]\)
为什么我们可以保证在 \([k+1,i]\) 这个区间不按保存键也能得到最优解?

实际上我们对 \(1\sim i-1\) 的每个位置都检验过按保存与否所能得到的最小期望,比如对于某点 \(j\in [1,i-1]\) ,一定是通过 \(1\sim j-1\) 中某个点保存后得到的最优解.只需要从 \(1\sim i-1\) 的点挨个转移过来即可.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<iomanip>
#define endl '\n'
#define pb push_back
using namespace std;
typedef pair<int,int> PII;
const int N = 1e5+10;
double cost[N];
double dp[N];

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int c,t,r;
	cin>>c>>t>>r;
	double p;
	cin>>p;
	for(int i =1;i<=c;i++)
	{
		cost[i] = ((cost[i-1])+1+p*r)/(1-p);
	}
	for(int i= 1;i<=c;i++)
	{
		dp[i] = cost[i];
		for(int k = 1;k<i;k++)
		{
			dp[i] = min(dp[i],dp[k]+cost[i-k]+t);
		}
	}
	cout<<fixed<<setprecision(12)<<dp[c]+t;
	
	return 0;
}

时间复杂度 \(\operatorname{O}(n^2)\)

H.House Numbering

给定一个 \(n\) 个结点, \(n\) 条边的无向图,每条边有 \(h\) 个房屋从 \(1~h\) 单向排列,你需要给出房屋的排列方向,需要满足如下规则

  • 一个点不能有两条或以上的边,这两条边的靠近该点的编号相同

\(\operatorname{Solution}\)
由于给定的图的点的个数和边的个数相同,因此这个图一定有且仅有一个环,然后有其他分支附在这个环上.

首先先找出这个环,然后按顺时针对分配每个点的房屋编号,检查是否有同一个点有两个相同的编号.若有则不合法,需要再按逆时针进行分配.同样按上述方法检查有效性.
时间复杂度 \(\operatorname{O}(n)\)

比赛总结

开赛时拿道题目后,看到许多题目都有ex人的小数点,觉得这场比赛并不简单.从赛后仅开出 \(3\) 道题的结果来看也确实是这样.
题目分配策略: \(ABCD\ |\ EFGH\ |\ IJKL\)
我们三人的策略是各自读一遍分配的四道题的题意,然后先初步想一下解法,读完题后互相讲题意,如果是签到可以简单交流或不交流,如果不是签到就后面两人或三人一同交流解法(不过三人一同交流同一道题的情况并不多).
经过简单交流后得到了签到 \(B,E,I\) ,经过上次题目读假导致浪费时间的教训,这次我特意多看了几遍题目并且认真验证了一遍样例,总算是没有出岔子.

E

\(E\) 题由于原文

There is one exception: total silence should always be preserved.

这句话没有理解清楚,导致 \(WA\) 了几发,还以为是 \(double\) 精度不够换成 \(long\ double\) 也不行,幸好队友及时发现并更正,这里 \(slience\) 应该翻译为沉默,也即声音为 \(0\) 时应该保持原样,交上去直接 \(AC\).这是由于英语导致的锅.

B

\(B\) 题签到过程还算顺利,与队友简单交流了几下,发现我原思路的一些问题,重新探讨后,发现没什么大问题队友上去写了一下,修改了一个小 \(bug\) 后很快 \(AC\) .

F

\(F\) 题基本上是队友一手包办,一发 \(A\) 掉.可惜队友写题时被隔壁队伍倒了一身水导致变相增长了一小段的(虽然可以忽略不计的)罚时

I

\(I\) 题这题本身是定位为签到题的,实际上这道题本身的难度也是签到题,然而由于一系列坑爹的原因,导致本来可以一发过的 \(I\) 最后 \(WA\) 连续三发后遗憾 \(3\) 题收尾,没有 \(K\) 掉这道签到题.
这题虽然队友给出了正确的方案,但是本题输出实在是有很大的坑,导致队友浪费了很多时间优化本来就不需要优化的算法,试过 \(double,long\ double\) ,"%lf","%Lf","%Le"等各种方法都 \(WA\) 掉,结果赛后用 %g 输出 \(double\) 就过了.
我们还是在 \(I\) 题的调试上花费了大量时间的,我认为这题完全可以归结到题目的锅.

L

\(L\) 题我们队是没打算做的.我们只有二维最近点对的模板,要由二维最近点对拓展到三维最近点对修改起来可能会比较麻烦,因此这题就搁置到尽量往后,如果有时间就去写,没时间就拉倒.
然而就在马上比赛结束的前五分钟看到一个队居然过了 \(L\) 题,后面队友与其他计算几何神犇交流后发现这题其实不难.然而比赛由于时间紧迫,没有过掉也是很正常的.

H

我还是花了不少时间在 \(H\) 这道题上,但是直到最后也没有弄出来解法,卒.

posted @ 2023-08-10 19:49  LZH_03  阅读(27)  评论(0编辑  收藏  举报