您的位置:首页 > 其它

河南省第一届程序设计竞赛___试题三 密码破译

2015-04-14 16:40 316 查看
【试题三】
密码破译 
 某组织欲破获一个外星人的密码,密码由一定长度的字串组成。此组织拥有一些破译此密码的长度不同的钥匙,若两个钥匙的长度之和恰好为此密码的长度,则此密码被成功破译。现在就请你编程找出能破译此密码的两个钥匙。 
 
【标准输入】 
    第一行: N                  N为钥匙的个数(1<=N<=1000) 
    第二行: L                  L为密码的长度 
以下有N行: Ai                每一行是一把钥匙的长度  i=1,2,……,N 
【标准输出】 
    若无法找到破译此密码的钥匙,则输出0
    若找到两把破译的钥匙,则输出文件有两行,分别为两把钥匙的编号,按从小到大输出。若有多种破译方案,则只输出包含起始编号最小的一组即可。
[【约束条件】
(1)1<= N,L,Ai <=1000    (  i=1, 2, ….., N )
(2)时间限制: 1000MS
【 样  例 】 
 
标准输入
标准输出
10 
80 
27 


73 
23 
68 
12 
64 
92 
16 
6
7
类型:组合;分治

 

解法:对所有可能的钥匙组合进行穷举是个方法,但应该注意到:要求两个钥匙的长度之和恰好为此密码的长度,那么其中一把钥匙的长度必定大于等于密码长度的一半。先对钥匙进行升序排序,然后使用二分搜索法定位到第一个大于L/2(L为密码的长度)的元素位置,得到相邻两钥匙的长度之和and,如果and大于L则向左端搜索,否则向右端搜索,遇到and==L,保存两把破译的钥匙的编号。搜索完毕还没有相符的and,则无法找到破译此密码的钥匙。最后,如果相符的and只有一个,则直接输出;如果相符的and有多个,则选择起始编号最小的一组数据输出。

#include<cstdio>

#include<algorithm>

#define MAX_N 1010

using namespace std;

int M,n;

int b[MAX_N];

struct Node{

 int x,value;

}a[MAX_N];

bool cmp(Node a,Node b){return a.value<b.value;}

int main()

{

 int m,nx,ny,np,nq;

 while(scanf("%d",&n)!=EOF){

  scanf("%d",&M);

  for(int i=1;i<=n;i++){

   scanf("%d",&m);

   a[i].x=i;

   a[i].value=m;

  }

  sort(a+1,a+n+1,cmp);

  for(int i=1;i<=n;i++)

      if(a[i].value>=M/2){

    nx=a[i].x;ny=i;break;

      }

  np=nq=1001;

  int p=ny-1,q=ny;

  while(p>=1&&q<=n){

   if(a[p].value+a[q].value>M)p--;

   else if(a[p].value+a[q].value<M)q++;

   else {

    if(min(a[p].x,a[q].x)<min(np,nq)){

     np=a[p].x;

     nq=a[q].x;

    }

    p--;q++;

   }

  }

  if(np==1001)printf("0\n");

  if(np>nq)printf("%d\n%d\n",nq,np);

  else printf("%d\n%d\n",np,nq);

 }

 return 0;

 

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: