B. Uniqueness(二分+离散化)

链接:http://codeforces.com/contest/1208/problem/B

题意:问去掉最小多少的一段能使所有不同数字的个数为1。

题解:以去掉的长度为基准进行二分,因为ai能到达1e9,所以还要离散化,然后直接暴力查询即可。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<stack> 
#include<cstring>
#include<map>
#include<queue> 
#include<cmath>
#include<set> 
#define INF 0x3f3f3f3f
#define lowbit(a) ((a)&-(a))
#define speed std::ios::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)
using namespace std;
typedef long long ll;
queue<int> q;
priority_queue<int> pq;  
const int maxn = 2005;
ll n,m;
ll ans=INF,cnt=0;
ll a[maxn],b[maxn];
bool check(ll x)
{
 ll c[maxn];
 ll i,j,k;
 for(i=1;i<=n-x+1;i++){
  memset(c,0,sizeof(c));
  for(j=1;j<=i-1;j++){
   c[a[j]]++;
   if(c[a[j]]>1)
    break;
  }
  for(k=i+x;k<=n;k++){
   c[a[k]]++;
   if(c[a[k]]>1)
    break;
  }
  if(k==n+1&&j==i)
   return true;
 }
 return false;
}
int main()
{
 cin>>n;
 for(int i=1;i<=n;i++) 
  cin>>a[i];
 for(int i=1;i<=n;i++) 
  b[i]=a[i];
 sort(b+1,b+n+1);
 for(int i=1;i<=n;i++) 
  if(b[i]!=b[cnt]) 
   b[++cnt]=b[i];
 for(int i=1;i<=n;i++) 
  a[i]=lower_bound(b+1,b+cnt+1,a[i])-b;
 /*for(int i=1;i<=n;i++) 
  cout<<a[i]<<endl;*/
 ll l=0,r=n-1,mid=(l+r)/2;;
 while(l<=r){
  //cout<<mid<<endl;
  if(check(mid)){
   r=mid-1,ans=min(mid,ans);
  }
  else
   l=mid+1;
  mid=(l+r)/2;
 }
 cout<<ans<<endl;
 return 0;
}

看到了tourist的做法,感觉可以学习一下vector容器离散化的方法和去重的手法,下面是他的代码和我的解释

#include <bits/stdc++.h>
 
using namespace std;
 
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> a(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  vector<int> b = a;
  sort(b.begin(), b.end()); //unique的返回值为不重复元素的最后一个位置 
  b.resize(unique(b.begin(), b.end()) - b.begin()); //重新调整b容器的大小为不重复元素的终点到起点大小 
  //cout<<b.size()<<endl; //unique去除相邻的重复元素 
  if ((int) b.size() == n) {  //如果相等则无重复 
    cout << 0 << '\n';
    return 0;
  }
  for (int i = 0; i < n; i++) {
    a[i] = (int) (lower_bound(b.begin(), b.end(), a[i]) - b.begin());
  } //离散化 
  int ans = 0;
  vector<int> mark(n, 0);v //二维数组,每项初始化为零 
  for (int i = 0; i < n; i++) { //左边 
    int take = 0;
    for (int j = 0; j < n; j++) { //从后面往前,右边 
      if (mark[a[n - 1 - j]] > 0) {  //如果大于零则说明加上这个数字则不符合要求了 
        break;
      }
      mark[a[n - 1 - j]] = 1; //标记已出现过 
      ++take; //记录取了几个数字 
    }
    ans = max(ans, i + take);  //i是左边取得数字,take是右边取得数字 
    for (int j = 0; j < take; j++) { 
      mark[a[n - 1 - j]] = 0; //将右边的数字还原 
    }
    if (mark[a[i]]) { //出现重复则说明左边走到终点了,不能再往下 
      break;
    }
    mark[a[i]] = 1; //记录这个数字已出现过 
  }
  cout << n - ans << '\n';
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
优化以下代码: FileMatrixVo fileMatrixVo = new FileMatrixVo(); fileMatrixVo.setId(tableName + "-" + columnName); fileMatrixVo.setCoherenceFiles(errorOutputFiles.stream().filter(errorOutputFileVo -> RuleTemplateName.ENUMERATION_CHECK.getId().equals(errorOutputFileVo.getRuleTemplateId())).collect(Collectors.toList())); fileMatrixVo.setEffectiveFiles(errorOutputFiles.stream().filter(errorOutputFileVo -> RuleTemplateName.REGEXP_CHECK.getId().equals(errorOutputFileVo.getRuleTemplateId())).collect(Collectors.toList())); fileMatrixVo.setCompleteFiles(errorOutputFiles.stream().filter(errorOutputFileVo -> RuleTemplateName.NULL_CHECK.getId().equals(errorOutputFileVo.getRuleTemplateId())).collect(Collectors.toList())); fileMatrixVo.setUniquenessFiles(errorOutputFiles.stream().filter(errorOutputFileVo -> RuleTemplateName.UNIQUENESS_CHECK.getId().equals(errorOutputFileVo.getRuleTemplateId())).collect(Collectors.toList())); fileMatrixVo.setMultiTableConsistency(errorOutputFiles.stream().filter(errorOutputFileVo -> RuleTemplateName.MULTI_TABLE_ACCURACY.getId().equals(errorOutputFileVo.getRuleTemplateId())).collect(Collectors.toList())); fileMatrixVo.setFieldLengthFiles(errorOutputFiles.stream().filter(errorOutputFileVo -> RuleTemplateName.FIELD_LENGTH_CHECK.getId().equals(errorOutputFileVo.getRuleTemplateId())).collect(Collectors.toList())); fileMatrixVo.setTimelinessFiles(errorOutputFiles.stream().filter(errorOutputFileVo -> RuleTemplateName.TIMELINESS_CHECK.getId().equals(errorOutputFileVo.getRuleTemplateId())).collect(Collectors.toList()));
最新发布
06-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值