【好好练习ACM-DAY1】

news2025/2/25 14:35:26

网站主要参照洛谷 牛客 力扣 cf等 

题单列表 - 洛谷

题单链接

今天的刷题内容如上

在进入专题学习之前

先看补充知识


数组能开多大

C/C++数组的大小最大能有多大?_c++数组大小_JoannaJuanCV的博客-CSDN博客

全局:int 2000*2000  6个0可 

局部: int 5个0可 char 6个0可

需要申请较大的空间->动态申请(new、malloc)


快读

快读/快写

快读/快写:只能处理整数读入/输出,但是要比标准输入输出函数都快得多。

  • 一般来讲,快读快写在针对数据量不是很大的输入输出的时候显得比较无力,但如果是多组数据或者输入量较多,就可以显著提升效率。
  • 开不开inline差不多。
  • 还有一种更快的fread()函数型快读,比一般的快读都要快,但是模板不太好理解。
inline int read(){
    int x=0,f=1;char c=getchar();
    //这里isdigit()也可以改为通过ASCII判断,isdigit=c>='0'&&c<='9'
    while(!isdigit(c))//#include<ctype>
    {if(c=='-')f=-1;
    c=getchar();}
    while(isdigit(c)){
    x=x*10+c-'0';
    c=getchar();}
    return x*f;
}

不过快读也有可能被卡,比如一个数据有很多很多空格

还没有见过如此毒瘤的数据

而实际上,甚至还有更快的读入方式:fread

这个函数的原理就是先把数 据流中的一整段都存下来,然后从这个数组里读取,直到数组读空了再重新从数据流中读取,由于是整段整段读取,所以自然比getchar()要快的多。

这两个东西在各种OJ上面还是适用的,因为OJ上就是文件读入输出的。

不过我们会发现,一旦用了这个读入优化。getchar,scanf都不能用了(存到buf里了),所有读入都必须自己写了。所以说数据流不是太大的时候(如1*10^6),可以考虑不用这个读入优化。

代码长这样↓

static char buf[1000000],*p1=buf,*p2=buf,obuf[1000000],*p3=obuf;
#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++
inline int read(){
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}

scanf:

1.使用scanf的时候最容易犯的也是最常见的问题就是没打取地址符,这个问题是不会CE,只会RE,但是一定要注意!scanf输入字符串本来也没有取地址符!

2.少一个或者多一个%d也是很常见的问题,多一个%d会因为找不到地址RE,少一个%d你的变量就会少值

3.文本替代符写错类型也是一个常见问题,尤其是%lld和%d,一定要确定好读入类型再写文本替代符

读入优化:

1.读入优化最最最最最容易出现的问题就是类型,虽然只能是int或者ll,但是一定要看好读入的的变量将会是什么类型,这里千万不能写错,ll写成int你题就炸了,int写成ll可能连赋值都做不到

2.只能用于整数,如果有什么浮点数建议直接放弃

3.写的时候一定要注意好别写错了,比如少个getchar之类的,如果没了会直接TLE或者RE

fread:(建议了解下即可)

1.同读入优化

2.只能使用文件读入

快写

内容基本与快读一致,此处将给出代码但不予赘述,请读者自行理解

快速读入唯一的问题是不能输出0,这里需要自行特判

以及fwrite可以在终端输入的情况下使用,但是会直接输出为文件形式

原初の快速输出↓

inline int read()
{  int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9')
        x=x*10+ch-'0',ch=getchar();
    return x*f;
}

fwrite快速输出↓

static char buf[1000000],*p1=buf,*p2=buf,obuf[1000000],*p3=obuf;
#define putchar(x) (p3-obuf<1000000)?(*p3++=x):(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=x)
inline void write(int x){ 
    if(x==0)
    {putchar('0');
    return;}
	int len=0,k1=x,c[10005];
	if(k1<0)
    k1=-k1,putchar('-');
	while(k1)
    c[len++]=k1%10+'0',k1/=10;
	while(len--)
    putchar(c[len]);
}


O2优化

我们不用管O2优化的原理,只需要记住这个优化能使得程序的效率大大提高

手动打开O2开关:

#pragma GCC optimize(2)

模拟

【算法1-1】模拟与高精度 - 题单 - 洛谷

[NOIP2003 普及组] 乒乓球

P1042 [NOIP2003 普及组] 乒乓球_哔哩哔哩_bilibili

#include<iostream>
using namespace std;
char a[2501*25+10];//每行至多25个字母,最多有2500行。

void work(int n)
{
    int w=0,l=0;
    for(int i=0;a[i]!='E';i++)
    {
        if(a[i]=='W') w++;
        else l++;
        if((w>=n&&w-l>=2)||(l>=n&&l-w>=2))//不要忽略题目中的每个信息
        {
            cout<<w<<":"<<l<<endl;
            w=l=0;
        }
    }
        cout<<w<<":"<<l<<endl;//不需要判断w!=0||l!=0
}
int main()
{
    int i=0;
    while(cin>>a[i]&&a[i]!='E')
    {
        i++;
    }
    work(11);
    cout<<endl;
    work(21);
    return 0;
}

P1067 [NOIP2009 普及组] 多项式输出

同判断三角形类型

高精度

加法

#include<bits/stdc++.h>
using namespace std;
string s1,s2;
int a[1000],b[1000];
int c[1000]={0};
void jiafa()
{
    int l1=s1.length();
    int l2=s2.length();
    for (int i=0;i<l1;i++)
        a[i]=s1[i]-'0';
    for(int i=0;i<l2;i++)
        b[i]=s2[i]-'0';
    int l=max(l1,l2);
    for(int i=0;i<l;i++)
    {
        c[i]+=a[i]+b[i];
        //进位
        if(c[i]>=10)
        {
            c[i+1]=c[i]/10;
            c[i]%=10;
        }
    }
    if(c[l]!=0) l++;

    for(int i=l-1;i>=0;i--)
        cout<<c[i];


}
void fanzhuan(string s)
{
	int l=s1.length();
	for(int i=0,j=l-1;i<j;i++,j--)
	{
		swap(s[i],s[j]);
	}
}
int main()
{
	cin>>s1>>s2;//空格 tab 换行都可下一个
	//cin.getline(s1);读一行
	//gets()太危险被禁用
	//fanzhuan(s1);
	reverse(s1.begin(),s1.end());
    reverse(s2.begin(),s2.end());
    jiafa();
    cout<<endl;
}

题目:P1601 A+B Problem(高精)

减法

#include<bits/stdc++.h>
using namespace std;
string s1,s2;
int a[1000],b[1000];
int d[1000]={0};
void jian(string s1,string s2)
{
    memset(a,0,sizeof(a));
	memset(b,0,sizeof(b));
	memset(d,0,sizeof(d));
//八位一复制
    int l1=s1.length();
    int l2=s2.length();
    for(int i=0;i<l1;i++)
        a[i]=s1[i]-'0';
    for(int i=0;i<l2;i++)
        b[i]=s2[i]-'0';
    int l=max(l1,l2);
    for(int i=0;i<l;i++)
    {
        d[i]+=a[i]-b[i];
        //借位问题
        if(d[i]<0)
        {
            d[i]+=10;//借位
            d[i+1]-=1;
        }
    }
    while(d[l-1]==0&&l>=1)
        l--;//借位借没了
int flag=0;
    for(int i=l-1;i>=0;i--)
        {cout<<d[i];
        flag=1;
        }
        if(flag==0)
            cout<<"0";
}
int judge(string s1,string s2)
{
    int l1=s1.length();
    int l2=s2.length();
    if(l1>l2) return 1;//长的数大
    if(l1<l2) return 0;
    for(int i=l1-1;i>=0;i--)
    {
        if(s1[i]>s2[i]) return 1;//一位一位比较 大的大
        if(s1[i]<s2[i]) return 0;
    }
    return 1;
}
void fanzhuan(string s)
{
	int l=s1.length();
	for(int i=0,j=l-1;i<j;i++,j--)
	{
		swap(s[i],s[j]);
	}
}
int main()
{
	cin>>s1>>s2;//空格 tab 换行都可下一个
	//cin.getline(s1);读一行
	//gets()太危险被禁用
	reverse(s1.begin(),s1.end());
    reverse(s2.begin(),s2.end());
    if(judge(s1,s2)==1) jian(s1,s2);
    else{
        cout<<"-";
        jian(s2,s1);
    }
}

乘法

#include<bits/stdc++.h>
using namespace std;
string s1,s2;
int a[1000],b[1000];
int c[1000]={0};

int cheng(string s1,string s2)
{
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    memset(c,0,sizeof(c));
    int l1=s1.length();
    int l2=s2.length();
    for(int i=0;i<l1;i++)
        a[i]=s1[i]-'0';
    for(int i=0;i<l2;i++)
        b[i]=s2[i]-'0';
    int l=l1+l2-1;/
    for(int i=0;i<l1;i++)
        for(int j=0;j<l2;j++)
    {
        c[i+j]+=a[i]*b[j];+
    }
    for(int i=0;i<l;i++)
    {
        if(c[i]>=10)
        {
            c[i+1]+=c[i]/10;//+
            c[i]%=10;
        }
    }
    while(c[l]>0)//这里l+1或者l都可以ac
    {
        l++;
        if(c[l]>=10)
        {
            c[l+1]+=c[l]/10;+
            c[l]%=10;
        }
    }
    for(int i=l-1;i>=0;i--)
        cout<<c[i];

}
int main()
{
	cin>>s1>>s2;
	reverse(s1.begin(),s1.end());
    reverse(s2.begin(),s2.end());
    cheng(s1,s2);
}

看着string里的reverse如此好用

我觉得去学一下STL中的string

string

于是去看了一篇博客

String用法详解_manonghouyiming的博客-CSDN博客

这里选取一部分内容放上

初始化

1)  string s;  // 生成一个空字符串s 
2)  string s(str) ; // 拷贝构造函数生成str的复制品 
3)  string s(str, stridx);  // 将字符串str内"始于位置stridx"的部分当作字符串的初值 
4)  string s(str, stridx, strlen) ; // 将字符串str内"始于stridx且长度顶多strlen"的部分作为字符串的初值 
5)  string s(cstr) ;  // 将C字符串(以NULL结束)作为s的初值 
6)  string s(chars, chars_len) ;  // 将C字符串前chars_len个字符作为字符串s的初值。 
7)  string s(num, ‘c’) ;  // 生成一个字符串,包含num个c字符 
8)  string s(“value”);  string s=“value”;  // 将s初始化为一个字符串字面值副本
9)  string s(begin, end);  // 以区间begin/end(不包含end)内的字符作为字符串s的初值 
10) s.~string();  //销毁所有字符,释放内存 

这里写图片描述

 string对象的操作

string s;
1)  s.empty();  // s为空串 返回true
2)  s.size();  // 返回s中字符个数 类型应为:string::size_type
3)  s[n];  // 从0开始相当于下标访问
4)  s1+s2;  // 把s1和s2连接成新串 返回新串 
5)  s1=s2;  // 把s1替换为s2的副本
6)  v1==v2;  // 比较,相等返回true
7)  `!=, <, <=, >, >=`  惯有操作 任何一个大写字母都小于任意的小写字母


当进行string对象和字符串字面值混合连接操作时,+操作符的左右操作数必须至少有一个是string类型的:

string s1(“hello”);
string s3=s1+”world”;  //合法操作
string s4=”hello”+”world”;  //非法操作:两个字符串字面值相加


4、字符串操作函数

1、string类函数
1) =, s.assign() // 赋以新值 
2) swap() // 交换两个字符串的内容 
3) +=, s.append(), s.push_back() // 在尾部添加字符 
4) s.insert() // 插入字符 
5) s.erase() // 删除字符 
6) s.clear() // 删除全部字符 
7) s.replace() // 替换字符 
8) + // 串联字符串 
9) ==,!=,<,<=,>,>=,compare() // 比较字符串 
10) size(),length() // 返回字符数量 
11) max_size() // 返回字符的可能最大个数 
12) s.empty() // 判断字符串是否为空 
13) s.capacity() // 返回重新分配之前的字符容量 
14) reserve() // 保留一定量内存以容纳一定数量的字符 
15) [ ], at() // 存取单一字符 
16) >>,getline() // 从stream读取某值 
17) << // 将谋值写入stream 
18) copy() // 将某值赋值为一个C_string 
19) c_str() // 返回一个指向正规C字符串(C_string)的指针 内容与本string串相同 有’\0’ 
20) data() // 将内容以字符数组形式返回 无’\0’ 
21) s.substr() // 返回某个子字符串 
22) begin() end() // 提供类似STL的迭代器支持 
23) rbegin() rend() // 逆向迭代器 
24) get_allocator() // 返回配置器

2、函数说明
1、s.assign();
s.assign(str); // 不说 
s.assign(str,1,3); // 如果str是"iamangel" 就是把"ama"赋给字符串 
s.assign(str,2,string::npos); // 把字符串str从索引值2开始到结尾赋给s 
s.assign("gaint"); // 不说 
s.assign("nico",5); // 把’n’ ‘I’ ‘c’ ‘o’ ‘\0’赋给字符串 
s.assign(5,'x'); // 把五个x赋给字符串

排序

冒泡排序、选择排序、快速排序

//快速排序
#include<iostream>
using namespace std;
 
int partition(int arr[], int low, int high) {
	int num = arr[low];
	while(low < high) {
		while(low < high && arr[high] > num) {
			high--;
		}
		arr[low] = arr[high];
		while(low < high && arr[low] <=num) {
			low++;//此处是<=num  并且 while不要忘记low<high
		}
		arr[high] = arr[low];
	}
	arr[low] = num;
	return low;//返回low
}
 
void QuickSort(int arr[],int L,int R)
{
	if(L<R){
		int mid=partition(arr,L,R);
		QuickSort(arr,L,mid-1);
		QuickSort(arr,mid+1,R);
	}
}
void BubbleSort(int arr[],int n)
{
	for(int i=0;i<n-1;i++)
	{
		for(int j=i+1;j<n;j++)
		{
			if(arr[i]>arr[j])
			{
				int temp=arr[i];
				arr[i]=arr[j];
				arr[j]=temp;
			}
		}
	}
}
void ChooseSort(int arr[],int n)
{
	int minnum;
	for(int i=0;i<n-1;i++)
	{
		minnum=i;
		for(int j=i+1;j<n;j++)
		{
		if(arr[minnum]>arr[j])
			minnum=j;
		}	
		int temp=arr[i];
		arr[i]=arr[minnum];
		arr[minnum]=temp;
	}
	
}
void travel(int arr[],int n)
{
	for(int i=0;i<n;i++)
		cout<<arr[i]<<" ";
	
	cout<<endl;
	
}
int main()
{
	int x;
	int a[100],b[100],c[100];
	int n=0;
	cin>>x;
	while(x!=0)
	{
		a[n]=x;
		b[n]=x;
		c[n]=x;
		cin>>x;
		n++;
	}
//	travel(a,n);
	BubbleSort(a,n);
	ChooseSort(b,n);
	QuickSort(c,0,n-1);
	travel(a,n);
	travel(b,n);
	travel(c,n);
}

插入排序(O(n^2))

void DirecInsSort(int* a, int n)//直接插入排序函数
{
    int i, j,temp;
 
    for (i = 1; i < n; i++) {//第一个数默认排序好了,而他的下标是0,所以从1开始
        if (a[i] < a[i - 1])//如果大于就直接加入,就是相当于排好了
        {
            temp = a[i];
            for (j = i - 1; j >= 0 && temp < a[j]; j--)//从已经排好的序列,从后往前检查
            {
                a[j + 1] = a[j];//往后移一个位置
            }
            a[j + 1] = temp;
        }
    }
}

希尔排序

注意:数组最后一个数一定要为1

//希尔排序
//8 3 6 1 68 12 19 3 1 0
#include<iostream>
using namespace std;
void Shell(int a[],int n,int incr)
{
	int j;
for(int i=0;i+incr<n;i++)//i++哦
{
	int x=a[i+incr];
	for( j=i;j>=0;j-=incr)
	{
		if(x<a[j]) //18<10
		{
			a[j+incr]=a[j];
		}
		else break;
	}
	a[j+incr]=x;
}
}
void ShellSort(int a[],int n,int d[])
{
	for(int i=0;i<3;i++)
	{
		Shell(a,n,d[i]);
		for(int j=0;j<n;j++)
			cout<<a[j]<<" ";
		
		cout<<endl;
	}
}
int main()
{
	int a[100],n,i=0;
	while(cin>>a[i]&&a[i])//输入数据 
		i++;  
	n=i;
	int d[10];//incr
	cin>>d[0]>>d[1]>>d[2];
	ShellSort(a,n,d);
 } 
void Shell(int a[],int n,int incr)
{
	int j;
	for(int i=incr;i<n-incr;i++)
	{
		if(a[i]<a[i-incr])
		{
			int temp=a[i];
			for(j=i-incr;j>=0&&a[j]>temp;j-=incr)
			{
				a[j+incr]=a[j];
			}
			a[j+incr]=temp;
		}
	}
}

归并排序

#include<bits/stdc++.h>
using namespace std;
void Merge(int Arr[],int start,int mid,int endd)
{
    int temp[10010];
    int i=start,j=mid+1,k=start;
    while(i!=mid+1&&j!=endd+1)
    {
        if(Arr[i]>Arr[j])
            temp[k++]=Arr[j++];
        else
            temp[k++]=Arr[i++];
    }
    while(i!=mid+1)
        temp[k++]=Arr[i++];
    while(j!=endd+1)
        temp[k++]=Arr[j++];
    for(i=start;i<=endd;i++)
        Arr[i]=temp[i];
}
void MergeSort(int a[],int start,int endd)
{
    int mid;
    if(start<endd)
    {    mid=start+(endd-start)/2;
        MergeSort(a,start,mid);
        MergeSort(a,mid+1,endd);//左右两块
        Merge(a,start,mid,endd);  }
}
int main()
{
    int n;
    int a[10010];
    cin>>n;
    for(int i=0;i<n;i++) cin>>a[i];
    MergeSort(a,0,n-1);
    for(int i=0;i<n;i++) cout<<a[i]<<" ";
    return 0;
}

第二种写法(一个函数):

void msort(int b,int e)//归并排序
{
    if(b==e)  
		return;
    int mid=(b+e)/2,i=b,j=mid+1,k=b;
    msort(b,mid),msort(mid+1,e);
    while(i<=mid&&j<=e)
    	if(a[i]<=a[j])
    		c[k++]=a[i++];
    	else
    		c[k++]=a[j++],ans+=mid-i+1;//统计答案
    while(i<=mid)
    	c[k++]=a[i++];
    while(j<=e)
    	c[k++]=a[j++];
    for(int l=b;l<=e;l++)
    	a[l]=c[l];
} 

堆排序

可移步这道题第二篇题解 我觉得写的非常好!!!

登录 - 洛谷

//堆排序
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
 
void SiftAdjust(int a[],int n,int i)
{
	//n是a数组有效数据的范围,它是慢慢变小的
	//i是要调整的那个节点的编号 
	int f,left;//f 用来记忆双亲 left算出i的左孩子编号 
	for(f=i,left=2*i+1;left<=n-1;)//计算新的孩子
	{//f记下要调整的i号节点,keft就变成右孩子的下标 
		if(left+1<=n-1 && a[left]<a[left+1] )//右孩子存在,且,右边值更大 
			left=left+1;//left++  left就变成右孩子的下标 
		if(a[left]>a[f])//孩子的最大值和双亲f比,若孩子更大,则交换 
		{
			int t=a[left];
			a[left]=a[f];
			a[f]=t;
		}
		else break; //孩子的值 小,就结束 return  
		f=left; //继续向下调整,刚才的孩子成为新的双亲,再上去计算新的孩子 
		left=2*f+1; //计算出新孩子,这句话放for表达式3也可以 
	}
	
}
void HeapSort(int a[],int n)
{
	//8 3 6 1 68 12 19 3 1
	//k=0 1 2 3 4 5 6 7 8
	//调整 中间节点 
	for(int i=(n-2)/2;i>=0;i--)
	{
		SiftAdjust(a,n,i);
	 } 
	 //调整根节点 
	 	for(int j=0;j<n;j++)
			cout<<a[j]<<" ";	
		cout<<endl;
	for(int i=0;i<n-1;i++)
	{
		int t=a[n-1-i];// n-1 n-2 n-3 n-4
		a[n-1-i]=a[0];
		a[0]=t;//交换第一个与最后一个数
		SiftAdjust(a,n-1-i,0);//调整剩下n-1-i个 维护根 
	   	for(int j=0;j<n;j++)
			cout<<a[j]<<" ";
			
		cout<<endl;
	}
}
int main()
{
	int a[100],i=0;
     while(cin>>a[i]&&a[i])
     {
     	i++;
	 }
	 int n=i;
	 HeapSort(a,n);
	 return 0;
 } 

维护堆排序

void heapify(int arr[],int n,int i)
{
	int largest=i;
	int lson=i*2+1;
	int rson=i*2+2;
	
	if(lson<n && arr[largest]<arr[lson])
		largest=lson;
	if(rson<n&&arr[largest]<arr[rson])
		largest=rson;
	//找出三个节点中最大的节点 
	if(largest!=i)
	{
		swap(&arr[largest],&arr[i]);
		heapify(arr,n,largest);
	}
 } 

桶排序

桶排序是计数排序的升级版,也是分治算法。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。简言之,将值为i的元素放入i号桶,最后依次把桶里的元素倒出来。

具体移步:https://blog.csdn.net/m0_64036070/article/details/123826962​​​​​​​

#include<bits/stdc++.h>
using namespace std;
int a,n,m,b[1000];
int main()
{
	cin>>n>>m;
	for(int i=0;i<m;i++)cin>>a,++b[a]; //记录票出现的次数
	for(int i=0;i<1000;i++)while(b[i]--)cout<<i<<" "; //根据票出现的次数输出
	return 0;
}

总结:

比赛:小数据用插入;大数据用快排

P1923 【深基9.例4】求第 k 小的数

思路 1 (60pts): O(nlog2​n)

想法:对原数组进行快速排序,然后 O(1) 输出。

#include<bits/stdc++.h>
using namespace std;
int x[5000005],k;
int main()
{
	int n;
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++)
		scanf("%d",&x[i]);
	sort(x,x+n);//快排
	printf("%d",x[k]);
}

思路 2 (100pts): O(n)

想法:根据快排思想来寻找第 k 小的数。

快排的核心思想是二分。

在原二分的基础上可以进行修改:因为每次递归都会将数组划分为三部分,而答案只会在这三部分中的一个,不需要再对其他部分进行搜索,从而达到优化时间复杂度的效果。

#include<bits/stdc++.h>
using namespace std;
int x[5000005],k;
void qsort(int l,int r)
{
	int i=l,j=r,mid=x[(l+r)/2];
	do
	{
		while(x[j]>mid)
			j--;
		while(x[i]<mid)
			i++;
		if(i<=j)
		{
			swap(x[i],x[j]);
			i++;
			j--;
		}
	}
	while(i<=j);
	//快排后数组被划分为三块: l<=j<=i<=r
	if(k<=j) qsort(l,j);//在左区间只需要搜左区间
	else if(i<=k) qsort(i,r);//在右区间只需要搜右区间
	else //如果在中间区间直接输出
	{
		printf("%d",x[j+1]);
		exit(0);
	}
}
int main()
{
	int n;
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++)
		scanf("%d",&x[i]);
	qsort(0,n-1);
}

思路 3 (100pts):O(n)

C++ 的宝库:STL

在 STL 里有一个神奇的函数 nth_element

它的用法是 nth_element(a+x,a+x+y,a+x+len);

结论:差不多就是将我们的思路 2 做了一遍。

nth_element 的时间复杂度是O(n) 的,不过 STL 常数普遍较大……但还是能过此题。

#include<bits/stdc++.h>
using namespace std;
int x[5000005],k;
int main()
{
	int n;
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++)
		scanf("%d",&x[i]);
	nth_element(x,x+k,x+n);//简短又高效
	printf("%d",x[k]);
}

在 Ta 的博客查看

刚翻了一下原来P1138第k小整数,发现竟然没人用nth_element神器,这里介绍一下。

在强大的STL库中存在一个神奇的函数,那就是nth_element,这个函数主要用来将数组元素中第k小的整数排出来并在数组中就位,随时调用,可谓十分实用。

函数语句:nth_element(数组名,数组名+第k小元素,数组名+元素个数)

具体如何用见下面AC代码:

#include<bits/stdc++.h>
using namespace std;
long long n,k,a[5000010];
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    nth_element(a,a+k,a+n);//使第k小整数就位 
    printf("%d",a[k]);//调用第k小整数
}

暴力枚举

加油

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/870104.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ubuntu删除大量磁盘文件时,内存cache降free升而创造的漂亮曲线

文章目录 前言图形本尊产生的原因总结 前言 最近在做压力测试&#xff0c;对磁盘、CPU、内存等指标比较敏感&#xff0c;因为产生了大量的日志文件需要定期删除&#xff0c;于是写了个定时清理磁盘的脚本&#xff0c;今天早上发现内存曲线居然产生了一个漂亮的图形&#xff0c…

递归、搜索与回溯算法

一.递归 &#xff08;1&#xff09;汉诺塔问题 当n2时&#xff0c;要将A中最下面盘子上方的盘子放到B上&#xff0c;最下面盘子放到C上&#xff0c;再将B上的盘子通过A放到C即可&#xff1b; 当n3时&#xff0c;要将A中最下面盘子上方的盘子放到B上&#xff0c;最下面盘子放到…

父进程等待子进程退出 / 僵尸进程孤儿进程

Q&#xff1a;父进程为什么要等待子进程退出&#xff1f; A&#xff1a;回顾创建子进程的目的&#xff0c;就是让子进程去处理一些事情&#xff0c;那么“事情干完了没有”这件事&#xff0c;父进程需要知道并收集子进程的退出状态。子进程的退出状态如果不被收集&#xff0c;…

系统架构设计专业技能 · 系统安全分析与设计(四)【加解密、数字信封、信息摘要、数字签名、数字书证、网络安全、信息安全】

系列文章目录 系统架构设计专业技能 网络规划与设计&#xff08;三&#xff09;【系统架构设计师】 系统架构设计专业技能 系统安全分析与设计&#xff08;四&#xff09;【系统架构设计师】 系统架构设计高级技能 软件架构设计&#xff08;一&#xff09;【系统架构设计师…

SQL 语句解析过程详解

SQL 语句解析过程详解&#xff1a; 1&#xff0e;输入SQL语句 2&#xff0e;词法分析------flex 使用词法分析器&#xff08;由Flex生成&#xff09;将 SQL 语句分解为一个个单词&#xff0c;这些单词被称为“标记“。标记包括关键字、标识符、运算符、分隔符等。 2.1 flex 原…

CCLINK转MODBUS-TCP网关cclink通讯接线图 终端电阻

大家好&#xff0c;今天我们要聊的是生产管理系统中的CCLINK和MODBUS-TCP协议&#xff0c;它们的不同使得数据互通比较困难&#xff0c;但捷米JM-CCLK-TCP网关的出现改变了这一切。 1捷米JM-CCLK-TCP是一款自主研发的CCLINK从站功能的通讯网关&#xff0c;它的主要功能是将各种…

JavaWeb 中对 HTTP 协议的学习

HTTP1 Web概述1.1 Web和JavaWeb的概念1.2 JavaWeb技术栈1.2.1 B/S架构1.2.2 静态资源1.2.3 动态资源1.2.4 数据库1.2.5 HTTP协议1.2.6 Web服务器 1.3 Web核心 2 HTTP2.1 简介2.2 请求数据格式2.2.1 格式介绍2.2.2 实例演示 2.3 响应数据格式2.3.1 格式介绍2.3.2 响应状态码2.3.…

linux中的ifconfig和ip addr

在linux操作系统中ifconfig和ip addr都是显示网卡配置信息的命令&#xff0c;好多人有疑惑它们有什么区别呢 区别1&#xff1a;对于linux发行的版本不一样 ip addr是对新发行版本的linux使用会比较多&#xff1b;而ifconfig是老版本遇到使用的会比较多。 区别2&#xff1a;显…

mysql8和mysql5的安装过程都有!!!超多图超详细保姆级教程最新教程新手小白轻松上手,带你了解清楚你安装过程的每一个术语

目录 前言mysql5和mysql8的区别1.官网下载2.mysql8的安装2.1安装程序打开前2.2Choosing a Setup Type选择安装模式2.3Select Products选择组件2.3.1Select Products的组件解释2.3.2Select Products的组件选择2.3.3电脑操作系统位数查看2.3.4Select Products的组件的内容配置2.3…

锐捷设备密码管理、密码恢复、恢复出厂设置

目录 配置登录用户名密码以及Enable密码 只需要密码登录 需要用户名和密码登录&#xff08;无AAA&#xff09; 需要用户名和密码登录&#xff08;有AAA&#xff09; 密码恢复 Web密码忘记 Telnet/SSH密码忘记 Console密码忘记 所有密码都忘记&#xff0c;通过Console进…

微信小程序在使用vant组件库时构建npm报错

在跟着vant官方进行使用步骤一步步操作时&#xff0c;由于要构建NPM&#xff0c;但NPM包在App配置文件的外部 所以在做下图这一步时&#xff1a; 接着再进行npm构建时会报错 message:发生错误 Error: F:\前端学习\前端框架\小程序\project\demo\miniprogram解决方法 &#xf…

Offset Explorer

Offset Explorer 简介下载安装 简介 Offset Explorer&#xff08;以前称为Kafka Tool&#xff09;是一个用于管理和使Apache Kafka 集群的GUI应用程序。它提供了一个直观的UI&#xff0c;允许人们快速查看Kafka集群中的对象以及存储在集群主题中的消息。它包含面向开发人员和管…

1、深入理解Mysql索引底层数据结构与算法(前置课程)

1.表中数据看似挨在一起&#xff0c;本质写在磁盘里&#xff0c;随着时间和其他程序占用可能分散分布 k为值 v为磁盘空间地址 2.为什么mysql选择B树 假如b树存放2k万数据 一个节点16KB&#xff0c;里面带有data的话存的太少&#xff0c;导致树的高度过高&#xff0c;所以让…

配置:Terminal和oh-my-posh

目录 命令行安装oh-my-posh查看安装情况配置PowerShell启用oh-my-posh、设置主题配色安装字体Terminal中的配置 命令行安装oh-my-posh Set-ExecutionPolicy Bypass -Scope Process -Force; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString(https://ohmy…

Java四大查找(二)插值查找

Java四大查找 一. 插值查找1.1 题目1.2 思路分析&#xff08;图解加文字&#xff09;1.3 代码演示 一. 插值查找 1.1 题目 给定一个有序数组&#xff0c;在有序数组中找到该数字。如果有&#xff0c;则返回该数字的下标&#xff0c;如果没有&#xff0c;则返回-1. 1.2 思路分析…

模拟IIC——关于模拟IIC的IO口的配置选取推挽输出还是开漏输出,以及是否需要更改IO口输入输出模式和是否需要对IO配置上拉

问题如下 当时我以为引脚配错了&#xff0c;原理图明明是B引脚&#xff0c;为何程序是C呢 查了一下资料&#xff0c;顿悟了 https://blog.csdn.net/m0_62243928/article/details/125779308 在使用模拟IIC的时候&#xff0c;观看别人的程序的时候发现了程序之间的一些不一…

RabbitMQ工作流程详解

1 生产者发送消息的流程 (1)生产者连接RabbitMQ&#xff0c;建立TCP连接(Connection)&#xff0c;开启信道(Channel) (2)生产者声明一个Exchange (交换器)&#xff0c;并设置相关属性&#xff0c;比如交换器类型、是否持久化等 (3)生产者声明一个队列井设置相关属性&#xf…

2023国赛数学建模B题思路分析

文章目录 0 赛题思路1 竞赛信息2 竞赛时间3 建模常见问题类型3.1 分类问题3.2 优化问题3.3 预测问题3.4 评价问题 4 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 竞赛信息 全国大学生数学建模…

2023国赛数学建模A题思路分析

文章目录 0 赛题思路1 竞赛信息2 竞赛时间3 建模常见问题类型3.1 分类问题3.2 优化问题3.3 预测问题3.4 评价问题 4 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 竞赛信息 全国大学生数学建模…

安卓:网络框架okhttp

目录 一、okhttp介绍 1. OkHttpClient类&#xff1a; 常用方法&#xff1a; 2. Request类&#xff1a; 常用方法&#xff1a; 3. Response类&#xff1a; 常用方法&#xff1a; 4. Call类&#xff1a; 常用方法&#xff1a; 5. Interceptor接口&#xff1a; 常用方法&…