专栏文章

题解:CF2093F Hackers and Neural Networks

CF2093F题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mipln8qk
此快照首次捕获于
2025/12/03 14:01
3 个月前
此快照最后确认于
2025/12/03 14:01
3 个月前
查看原文
可以通过几个结论推出做法。
1.对于目标字符串数组 a[n]a [n] ,只有所有 a[i]a [i] 都能在下面至少一个对应的位置 b[i]b[i] 找到,才有答案~~(那不然怎么拼好串)~~。
那要是没答案,就输出 1-1 就好了。
2.现在就是有答案的情况了:
我们不关心具体怎么拼出这个串,我们只要求最小次数。
在已有一个部分匹配的串的基础上:
如果进行操作 22 擦除再操作 11 加入,很显然要 22 次才可以纠正一个位置的字符串,所以我们要尽可能让这个部分匹配的串尽可能多匹配一些(初始匹配只要一次)。
具体实现也很简单,只需要遍历找出和 aa 重合度最高的那个 bb 即可。
答案初始为 ans=0ans = 0
bb 加进来则 ans=ans+nans = ans + n
现在 ans=nans = n
后续修改,由于已经除去了不成立的情况,剩下一定可以找到一个 bb 满足条件,则只需要加 ansans 即可。
容易知道,每有一个不同的字符串 ans=ans+2ans = ans + 2 (修改计 22 次)。
代码如下:
CPP
#include<iostream>
#include<cstdio>
#include<cstring>
#define INF 505
using namespace std;
int n,m;
int cnt[INF];
bool vis[INF];
void solve()
{
	scanf("%d%d",&n,&m);
	memset(vis,0,sizeof(vis));
	memset(cnt,0,sizeof(cnt));
	string strtar[INF];
	string str[INF][INF];
	for(int i=1;i<=n;i++)
	{
		cin>>strtar[i];
	}
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cin>>str[i][j];
			if(str[i][j]==strtar[j])
			{
				vis[j]=1;
				cnt[i]++;
			}
		}
	}
	int sum=0;
	for(int i=1;i<=n;i++)
	sum+=vis[i];
	if(sum<n)
	{
		puts("-1");
		return;
	}
	
	int maxn=-1;
	for(int i=1;i<=m;i++)
	maxn=max(maxn,cnt[i]);
	
	int ans=n+(n-maxn)*2;
	printf("%d\n",ans);
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		solve();
	}
	return 0;
}
(第一次写没加句号被打回了,审核大人辛苦了)

评论

0 条评论,欢迎与作者交流。

正在加载评论...