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];//把新申请的数组全部初始化为0for (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。如果我们从头到尾依次异或数组中的每一个数,那么最终的结果就是那个只出现一次的数字,因为其他出现两次的数字全部在异或中被抵消为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;}} }