平方映射
//1078 平方探测
#include<bits/stdc++.h>
using namespace std;
bool isprime(int n){
if(n<=1) return false;
for(int i=2;i<=sqrt(n*1.0);i++){//<= 4.5 4本来可以<就漏掉了
if(n%i==0) return false;
}
return true;
}
int main(){
int ms,n,_1;
scanf("%d%d",&ms,&n);
while(!isprime(ms)) ms++;
int book[ms],book1[ms];
fill(book1,book1+ms,0);
map<int,int> ans;
for(int i=0;i<n;i++){
scanf("%d",&_1);
ans[_1]=-1;
for(int j=0;j<ms;j++){
if(book1[(_1+j*j)%ms]==0){
book[(_1+j*j)%ms]=_1;
ans[_1]=(_1+j*j)%ms;
book1[(_1+j*j)%ms]=1;
break;
}
}
if(i!=0) printf(" ");
if(ans[_1]>=0)
printf("%d",ans[_1]);
else printf("-");
}
return 0;
}
//平方探测法
//1145
#include<bits/stdc++.h>
using namespace std;
bool isprime(int x){
if(x<=1) return false;
for(int i=2;i<=sqrt(x*1.0);i++){
if(x%i==0) return false;
}
return true;
}
int main(){
int ms,n,m,_1;
scanf("%d%d%d",&ms,&n,&m);
//if(!isprime(ms)) ms++;//本来应该用while又用成了if while才能实现循环找值 昨天也是这么错的 把while 写成if 1
while(!isprime(ms)) ms++;
int book[ms] ,book1[ms] ;
fill(book,book+ms,0);
fill(book1,book1+ms,0);
for(int i=0;i<n;i++){
int flag=1;
scanf("%d",&_1);
int j;
for( j=0;j<ms;j++){//忘记插入后直接break
int _4=(_1+j*j)%ms;
if(book1[_4]==0){
book[_4]=_1;
book1[_4]=1;
flag=0;
break;
}
}
if(flag==1) printf("%d cannot be inserted.\n",_1);
}
int sum=0,_2;
for(int i=0;i<m;i++){
scanf("%d",&_2);
for(int j=0;j<=ms;j++){
sum++;
int _3=(_2+j*j)%ms;
if(book1[ _3]==0||book[ _3]==_2) break;
}
}
printf("%.1lf\n",sum*1.0/m);
return 0;
}
堆排序
//堆排序
#include<bits/stdc++.h>
using namespace std;
//向下调整
int heap[100],n=10;
void downadjust(int low,int high){
int i=low,j=2*i;
while(j<=high){
if(j+1<=high){
if(heap[j+1]>heap[j]){
j=j+1;
}//选左右结点中的最大值
}
if(heap[i]<heap[j]){
swap(heap[i],heap[j]);
i=j;//始终令i为调整节点
j=2*i;//左节点
}else{
break;
}
}
}
void create(){
for(int i=n/2;i>=1;i--){
downadjust(i,n);
} //n/2为树的最后一个非叶节点
}
void deletetop(){//删除栈顶元素
heap[1]=heap[n--];
downadjust(1,n);
}
//插入元素需要用到的向上调整
void upadjust(int low,int high){
int i=high;
int j=i/2;//双亲
while(j>=low){
if(heap[i]>heap[j]){
swap(heap[i],heap[j]);
i=j;
j=i/2;
}else{
break;
}
}
}
//插入元素
void insert(int x){
heap[++n]=x;
upadjust(1,n);
}
void heapsort(){
create();//建堆
for(int i=n;i>1;i--){
swap(heap[1],heap[i]);
downadjust(1,i-1);//i-1
}
}
int main(){
int _1;
for(int i=1;i<=10;i++){
scanf("%d",&_1);
heap[i]=_1;
}
insert(101);//1 insert 无误向上调整无误
heapsort();//2向下调整 3建堆无误
for(int i=1;i<=n;i++){
printf(" %d",heap[i]);
}
return 0;
}
//堆排序复盘
#include<bits/stdc++.h>
using namespace std;
int heap[100],n=10;
void downadjust(int low,int high){
int i=low,j=2*i;
while(j<=high){
if(j+1<=high&&heap[j+1]>heap[j]){//3 j+1也要验证是否在范围内是否存在
j=j+1;
}
if(heap[j]>heap[i]){
swap(heap[j],heap[i]);
i=j;
j=2*i;
}else{
break;
}
}
}
void deletetop(){
swap(heap[1],heap[n--]);
downadjust(1,n);
}
void create(){
for(int i=n/2;i>=1;i--){
downadjust(i,n);
}
}
void upadjust(int low,int high){
int i=high,j=i/2;
while(j>=low){
if(heap[i]>heap[j]){
swap(heap[i],heap[j]);
i=j;
j=i/2;
}else{
break;
}
}
}
void insert(int x){
heap[++n]=x;
upadjust(1,n);
}
void heapsort(){
create();
for(int i=n;i>1;i--){
swap(heap[i],heap[1]);
downadjust(1,i-1);
}
}
int main(){
int _1;
for(int i=1;i<=n;i++){
scanf("%d",&_1);
heap[i]=_1;
}
insert(101);
deletetop();
heapsort();
for(int i=1;i<=n;i++){
printf(" %d",heap[i]);
}
printf("\n");
return 0;
}
/* 4 5 68 4 2 1 7 6 3 7
//直接插入排序不是最终位置 需要相对检查 堆排序是最终位置可以和直接最终位置比对
//1098
#include<bits/stdc++.h>
using namespace std;
int heap[110],insert[110],n;
void downadjust(int low,int high){
int i=low,j=2*i;
while(j<=high){
if(j+1<=high&&insert[j+1]>insert[j]){
j=j+1;
}
if(insert[j]>insert[i]){
swap(insert[j],insert[i]);
i=j;
j=2*i;
}else {
break;
}
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&heap[i]);
}
for(int i=1;i<=n;i++){
scanf("%d",&insert[i]);
}
int pre= insert[1],nt;
for(int i=2;i<=n;i++){
if(insert[i]>=pre){
pre=insert[i];
}else{
nt=i;
break;
}
}
int flag=1;
for(int i=nt;i<=n;i++){
if(heap[i]!=insert[i]){
flag=0;
}
}
if(flag==1){
printf("Insertion Sort\n");
sort(heap+1,heap+nt+1);
for(int i=1;i<=n;i++){
if(i!=1) printf(" ");
printf("%d",heap[i]);
}
}else{
printf("Heap Sort\n");
sort(heap+1,heap+n+1);
int cnt;
for(int i=n;i>=1;i--){
if(insert[i]!=heap[i]){
cnt=i;
break;
}
}
swap(insert[1],insert[cnt]);
downadjust(1,cnt-1);
for(int i=1;i<=n;i++){
if(i!=1) printf(" ");
printf("%d",insert[i]);
}
}
return 0;
}
归并排序
//归并排序
#include<bits/stdc++.h>
using namespace std;
const int maxn=100;
int n;
void merge(int a[],int l1,int r1,int l2 ,int r2){
int i=l1,j=l2;
int temp[maxn],index=0;
while(i<=r1&&j<=r2){
if(a[i]<=a[j]){
temp[index++]=a[i];
i++;
}else{
temp[index++]=a[j];
j++;
}
}
while(i<=r1) temp[index++]=a[i++];
while(j<=r2) temp[index++]=a[j++];
for(int i=0;i<index;i++){
a[l1+i]=temp[i];
}
}
void mergesort(int a[]){
for(int step=2;step/2<=n;step*=2){
for(int i=1;i<=n;i+=step){
int mid=i+step/2-1;//左半区间的最后一个
if(mid+1<=n)//有可能不存在右子区间
merge(a,i,mid,mid+1,min(i+step-1,n));
}
}
}
void mergesortfz(int a[]){
for(int step=2;step/2<=n;step*=2){
for(int i=1;i<=n;i+=step){
sort(a+i,a+min(n+1,i+step));//sort,reverse左闭右开
}
}
}
int main(){
int a[maxn];n=10;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
mergesort(a);//使用merge
//mergesortfz(a);//sort模拟
for(int i=1;i<=n;i++){
printf(" %d",a[i]);
}
printf("\n");
}
//1089 差点被这题坑死 测试点4 5有问题,把编译器从clang 编程g++ 就完美通过了
#include<bits/stdc++.h>
using namespace std;
int init[100],then[100],n;
void mergesort(int a[]){
for(int step=2;step/2<=n;step*=2){
int flag=0;
for(int i=1;i<=n;i++){
if(then[i]!=a[i])//这里出现问题应该是过程中的a 而不是直接带入init
flag=1;
}
for(int i=1;i<=n;i+=step){
sort(a+i,a+min(i+step,n+1));
}
if(flag==0){
for(int i=1;i<=n;i++){
if(i!=1) printf(" ");
printf("%d",a[i]);
}
break;//忘记
}
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&init[i]);
}
for(int i=1;i<=n;i++){
scanf("%d",&then[i]);
}
int pre=then[1],nt;
for(int i=2;i<=n;i++){
if(pre<=then[i]){
pre=then[i];
}else{
nt=i;
break;
}
}
int flag=0;
for(int i=nt;i<=n;i++){
if(init[i]!=then[i]){
// break;//break跑到标志前出错
flag=1;
break;
}
}
if(flag==0){
printf("Insertion Sort\n");
sort(then+1,then+nt+1);
for(int i=1;i<=n;i++){
if(i!=1) printf(" ");
printf("%d",then[i]);
}
}else{
printf("Merge Sort\n");
/*int step;
int pre1=then[1];
for(int i=2;i<=n;i++){
if(pre1<=then[i]){
pre1=then[i];
}else{
step=i-1;//各个组之间未必有这样的大小关系
break;
}
}
mergesort(then,step);
for(int i=1;i<=n;i++){
if(i!=1) printf(" ");
printf("%d",then[i]);
}*/
mergesort(init);
}
return 0;
}
快速排序
//快速排序
#include<bits/stdc++.h>
using namespace std;
int partition(int a[],int left,int right){
int temp=a[left];
while(left<right){
while(left<right&&temp<a[right]) right--;//指针是不断移动的
a[left]=a[right];
while(left<right&&temp>=a[left]) left++;
a[right]=a[left];
}
a[left]=temp;
return left;
}
void kysu(int a[],int left,int right){
if(left<right){
int mid=partition(a,left,right);
kysu(a,left,mid-1);
kysu(a,mid+1,right);
}
}
int main(){
int a[10];
for(int i=0;i<10;i++){
scanf("%d",&a[i]);
}
kysu(a,0,9);
for(int i=0;i<10;i++){
printf(" %d",a[i]);
}
return 0;
}
//除了在最终位置上还有保证左小右大
//1101
#include<bits/stdc++.h>
using namespace std;
vector<long long > init,ccopy;
set<long long> ans;
//const int inf=100000000;//10^9最大值少一个0都不行
const int inf=1000000000;
int main(){
int n;
long long _1;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%lld",&_1);
init.push_back(_1);
}
ccopy=init;
int bookmin[n],bookmax[n],mx=0,mn=inf;
fill(bookmin,bookmin+n,inf);
//fill(bookmax,bookmax+n,0);
for(int i=n-1;i>=0;i--){
if(ccopy[i]<mn){
mn=ccopy[i];
bookmin[i]=mn;
}
}
sort(init.begin(),init.end());
for(int i=0;i<n;i++){
if(ccopy[i]>mx) mx=ccopy[i];
if(init[i]==ccopy[i]&&ccopy[i]>=mx&&ccopy[i]<=bookmin[i]){//不是init init已经排过序了应该是原序列的情况
ans.insert(ccopy[i]);
}
}
printf("%d\n",ans.size());
for(auto it=ans.begin();it!=ans.end();it++){
if(it!=ans.begin()) printf(" ");
printf("%lld",*it);
}
printf("\n");
return 0;
}
二分查找 while(low<high)时返回位置 while(low<=high) 返回存不存在信息
//1010 //用了long long 一些正确了
#include<bits/stdc++.h>
using namespace std;
string n1,n2;
long long int swit(char a){
if(isdigit(a)){
return a-'0';
}else{
return a-'a'+10;
}
}
long long int findmax(string b){
long long int max=-1;
for(int i=0;i<b.size();i++){
long long int _2=swit(b[i]);
if(_2>max){
max=_2;
}
}
return max;
}
long long int jvswit(string c,long long int radix){
long long int sum=0,cnt=0;
for(int i=c.size()-1;i>=0;i--){
sum+=swit(c[i])*pow(radix,cnt);
cnt++;
}
return sum;
}
long long int erff(string d,long long int low,long long int high,long long int aim){
while(low<=high){
long long int mid=(low+high)/2;
long long int _6=jvswit(d,mid);
/* if(_6<aim){//溢出也可能小于如果放在上面会误判溢出点 ,if else 当不是相互独立又相互包含关系时,顺序也非常重要
low=mid+1;
}*/
if(_6>aim||_6<0){//位数太多可能溢出
high=mid-1;
}else if(_6==aim){
return mid;
}else{
low=mid+1;//将这里的判断条件顺序改了就过了
}
}
return -1;
}
int main(){
long long int tag,radix,_1,_2,_3,_4;
cin>>n1>>n2>>tag>>radix;
if(tag==1){
_1=jvswit(n1,radix);
_2=findmax(n2);
_4=max(_2+1,_1);//测试点1考察high不一定比low大此时要特判
_3=erff(n2,_2+1,_4,_1);
if(_3==-1){
printf("Impossible");
return 0;
}else{
printf("%d",_3);
}
}else{
_1=jvswit(n2,radix);
_2=findmax(n1);
_4=max(_2+1,_1);
_3=erff(n1,_2+1,_4,_1);
if(_3==-1){
printf("Impossible");
return 0;
}else{
printf("%d",_3);
}
}
return 0;
}
总结
有很多小细节 需要注意 二分查找里long long 溢出判断 if else 上下相互包含要注意顺序
归并排序 每一组之间未必有大小关系
堆排序 全局算法 向下调整
快速排序 除了位置要在最终位置上 还要满足左小右大
直接插入排序 不是全局性算法,注意他的验证方法
加油 棒棒da~