coeofrces 637C Problem Analysis

Codeforces Tutorial

C. Promocodes with Mistakes

Problem Analysis

题意:有n个长度均为6的校验码,要求最大的容错率k,使得对于任意一个校验码都可以判定其在不超过k个错误下为这n个校验码中的哪一个 。
之前没遇到过这种类型,学习了。
我们可以采用逆向思维来思考这个问题。
两个字符串的差异:
\[ strdif(s_1,s_2)=\sum_{k=0}^5 s_1[k]!=s_2[k] \]
对于任意的两个\(s_i\)\(s_j\),假设存在一个字符串 \(s_k\),和一个不合法的\(k\),使得
\[ strdif(s_i,s_k) \leq k \land strdif(s_j,s_k) \leq k \]
\[ strdif(s_i,s_j) \leq strdif(s_i,s_k)+strdif(s_j,s_k) \leq 2k \]
所以:

不合法的
\[ k \ge \frac{strdif(s_i,s_j)+1}{2} \]
那么合法的
\[ k \leq \frac{strdif(s_i,s_j)-1}{2} ,for \quad i,j \in \left[1,n\right] \land i \neq j \]

Acepted Code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cmath>
#include<map>
#include<istream>
#include<cassert>
#include<set>
#define DEBUG(x) cout<<#x<<" = "<<x<<endl
#define DEBUG2(x,y) cout<<#x<<" = "<<x<<" , "\
<<#y<<" = "<<y<<endl
using namespace std;
typedef long long ll;
int n;
char promocode[1100][10];
int strdif(char a[],char b[])
{
    int cnt=0;
    for(int ii=0;ii<6 ;ii++ ){
        if(a[ii]!=b[ii])cnt++;
    }
    return cnt;
}
int main()
{
//    freopen("in.txt","r",stdin);
    scanf("%d\n",&n);
    for(int ii=1;ii<=n ;ii++ ){
        scanf("%s",promocode[ii]);
    }
    int ans=6;
    for(int ii=1;ii<=n-1 ;ii++ ){
        for(int jj=ii+1;jj<=n ;jj++ ){
            ans=min(ans,(strdif(promocode[ii],promocode[jj])-1)/2);
        }
    }
    printf("%d\n",ans);
}

Wrong Answer Cases

Test 3

ans 的默认设置问题

What I Learn

这种解法实际上要求构造一个不合法的输入,根据这个不合法的输入,推断出\(k\)的要求。
核心就是\(k\)和不合法的输入是关联的。

Reference

https://blog.csdn.net/V5ZSQ/article/details/70854480

转载于:https://www.cnblogs.com/MalcolmMeng/p/10959871.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值