计蒜客第三场

1、有序数组查找

假设一个数组,事先在你未知的情况下,以某一点分段有序排列。比如:(0,0,0,1,2,2,3 变成 0,0,1,2,2,3,0,定需要查找的数,在当前数组中查找,存在,返回ture,不存在,返回false。注意,这次数组中有重复的数字哦~

格式:

第一行输入数字n,接下来一行输入数组A[n],数组A[n]满足题目描述的条件,即分段有序。如:(2, 2, 0, 0, 1, 1);第三行输入要查找的target值。接下来一行输出true或者false。

样例输入

7
1 2 2 2 0 1 1
0

样例输出

true
#include<iostream> 
#include<algorithm>
using namespace std; 
int main()
{
    int n;
    cin>>n;
    int a[n];
    for(int i=0;i<n;i++)
        cin>>a[i]; 
    int target,mid;
    cin>>target;
    sort(a,a+n);//对输入的数组排序
    int l=0, r=n-1;//二分查找
    while(r>=l){
        mid=(l+r)/2;
        /*if(target==a[mid]){
            cout<<"true"<<endl;
            return 0;
        }*/
        if(target>a[mid]) 
            l=mid+1;
        else if(target<a[mid]) 
            r=mid-1;
        else {
            cout<<"true"<<endl;
            return 0;
        } 
    }
    cout<<"false"<<endl;
    return 0;
}

2、特殊质数

7331是一个特殊的质数,因为我们去掉个位得到的733是一个质数;再次去掉个位得到的73又是一个质数;再去掉个位后得到的7依然是一个质数。对于形似这种的质数,我们称呼它为特殊质数。

写一个程序对给定的待求特殊质数的位数 N (1≤N≤8)求出所有对应位数的特殊质数(注意:数字1不被看作一个质数)。

输入包括一个整数,为待求特殊质数的位数 N。

输出长度为N的特殊质数列表,每行一个。

#include<iostream>
using namespace std;
int n;
bool IsPrime(int a){
    for(int i=2;i*i<a;i++){
        if(a%i==0)
            return false;
    }
    return true;
}
void dfs(int sum,int cur){
    if(cur==n)
        cout<<sum<<endl;
    for(int i=1;i<=9;i++){
        if(i%2==0)
            continue;
        int asum=sum*10+i;
        if(IsPrime(asum)){
            dfs(asum,cur+1);
        }
    }
}
int main(){
    while(cin>>n){
        dfs(2,1);
        dfs(3,1);
        dfs(5,1);
        dfs(7,1);
    }
    return 0;
}

 3、颜色排序

给定由n个图案,图案是红色,白色或者蓝色其中的一种,开始的时候他们的顺序是混乱的。请你设计一种排序算法,使得相同颜色的图案紧挨着,并且顺序为红,白,蓝。    为了方便,这里我们用0, 1, 2分别代替红白蓝三种颜色,请将他们排序出来~  看这个例子,如:2 2 1 0 1 2 0,排序后变成0 0 1 1 2 2 2  注意:你不能使用库函数里面的排序算法哦~    要求:时间复杂度 O(n),空间复杂度 O(1)   

格式:  第一行输入数字n,第二行输入A[n], 其中数组里面只包含0, 1, 2三个数。第三行输出排好序的A[n]   

样例输入: 

8 1 2 1 2 0 0 0 2

样例输出 :

0 0 0 1 1 2 2 2

void SortByN(int a[], int length)
{
    if (a == NULL || length < 0)
    {
        return;
    }
    //重新申请一个数组
    const int N =200;
    int b[N];
    //把新申请的数组全部初始化为0
    for (int i = 0; i < N; ++i)
    {
        b[i] = 0;
    }
    //遍历a数组
    for (int i = 0; i < length; ++i)
    {
        //例如:a[0] = 10;那么b[key] = b[10] = 1;表示有一个10; a[4] = 10;
        //那么b[key] = b[10] = 1+1 = 2,表示此时有两个10;
        int key = a[i];
        ++b[key];
        //意思就是b数组里面存放的是a数组中某个元素的个数,b[10]表示在a数
        //组当中10出现的次数,b[0]表示0在a数组当中出现的次数
    }
    int index = 0;
    for (int i = 0; i < N; ++i)
    {
        //如果b[0] = 0;表示a数组当中没有0;那么不执行这个循环;例如这里a是一个年龄数组,假设最小的年龄是18
        //那么b[0] -- b[17]都是等于0;那么第二个循环都不执行,第一个循环执行,i加到了18;b[18]=2;
        //那么a数组当中有两个18;而且这两个18就是最小的数字,那么a[0] = 18; a[1] = 18;
        for (int j = 0; j < b[i];++j)
        {
            a[index] = i;
            ++index;
        }
    }
}

4、单独的数字

一个整型数组中有一个元素只出现一次,其它元素都出现两次。求出只出现一次的元素。
要求:
线性时间复杂度,不能使用额外空间。
聪明的你能搞定吗?
格式:
第一行输入数字n,代表有n个数,根据题意,很明显n是奇数,
第二行输入数组A[i], i从0~n-1.
最后输出单独的数字。
样例1
输入:
7
1 3 2 0 3 2 1
输出:

/*那么这个题的突破口在哪里呢?注意这个数组的特殊性:其它数字都出现了两次,只有一个数出现了一次。可以想到运用异或运算,任何一个数字异或它自己都等于0。

           如果我们从头到尾依次异或数组中的每一个数,那么最终的结果就是那个只出现一次的数字,因为其他出现两次的数字全部在异或中被抵消为0了(异或运算遵循交换分配率)。

           举个栗子:2  3  4  2  3

           所有数字依次异或运算:2 xor 3 xor 4 xor 2 xor 3 = (2 xor 2) xor (3 xor 3) xor 4= 0 xor 0 xor 4 = 4

          最终结果4就是我们要找的那个只出现一次的数字。*/
#include<iostream>
using namespace std;
int main(){
    int num;
    int f(int a[],int n,int &num);
    int n;
    cin>>n;
    int a[n];
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    cout<<f(a,n,num)<<endl;
    return 0;
}
int f(int a[],int n,int &num){
    for(int i=0;i<n;i++)
        num^=a[i];
    return num;
}

 5、第一个没有出现的正数

给定一个数组,从 11 到 nn,找出数组中第一个没出现的正数。

例如:

给定[1,2,0],则返回 33。

给定[3,4,-1,1],则返回 22。

注意:

算法需要 mathcal{O}(n)O(n) 的时间复杂度以及线性的空间复杂度。

#include<iostream>
using namespace std;
int main()
{
    int n;
    cin>>n;
    int a[1000001]={0};
    int tmp;
    for(int i=0;i<n;i++){
        cin>>tmp;
        if(tmp>0) 
            a[tmp]++;
    }
    for(int i=1;i<=n;i++){
        if(a[i]==0){
            cout<<i;
            return 0;
        }
    }
}


























原文地址:https://www.cnblogs.com/geziyu/p/9665777.html