0)在G++不支持%lf,如果G++提交请用%f,如果C++提交请用%lf 。
1)next_permutation()【#include <algorithm>】
作用:求一个排序的下一个排列的函数,可以遍历全排列。
参考案例:Noip普及组2004 火星人
#include<bits/stdc++.h>
using namespace std;
int a[10005],n,m;
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
while(m--) next_permutation(a,a+n);
for(int i=0;i<n-1;i++) printf("%d ",a[i]); printf("%d",a[n-1]);
return 0;
}
与之完全相反的函数还有prev_permutation(就是一个求一个排序的上一个排列的函数)
一个不错的文章 http://blog.sina.com.cn/s/blog_9f7ea4390101101u.html
2) elelment【#include<algorithm>】
1.nth_element
作用:这个函数主要用来将数组元素中第k小的整数排出来并在数组中就位,随时调用,可谓十分实用。
#include<bits/stdc++.h>
using namespace std;
long long n,k,a[5000010];
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
nth_element(a+1,a+k+1,a+n);//使第k小整数就位
printf("%d",a[k]);//调用第k小整数
}

你会发现,第3大的数3到了该去的位置,并且在3前面的数都比3小,在3后面的数都比3大
2.max_element / min_element
#include <iostream>
#include <algorithm>
using namespace std;
int main(void)
{
int a[6] = {5, 3, 2, 6, 1, 4};
cout<<max_element(a, a+6) - a<<endl;// 输出为3
cout<<*max_element(a, a+6)<<endl;//输出为 6
cout<<min_element(a, a+6) - a<<endl;// 输出为4
cout<<*min_element(a, a+6)<<endl; //输出为1
return 0;
}
3)二分思路
如果题目规定了有“最大值最小”或者“最小值最大”的东西,那么这个东西应该就满足二分答案的有界性(显然)和单调性(能看出来)。
例题:洛谷 P2440 木材加工
#include<iostream>
#include<cstdio>
using namespace std;
int n,k,maxx=0,minn=200000000,ans=0;
int a[50000000];
bool judgee(int x)
{
int alll=0;
for(int i=1;i<=n;i++)
{
alll+=a[i]/x;
}
if(alll<k)return false;
else return true;
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(minn>a[i]) minn=a[i];
if(maxx<a[i]) maxx=a[i];
}
int mid,l=1,r=maxx;
while(l<=r)
{
mid=(l+r)/2;
if(judgee(mid))
{
ans=mid;
l=mid+1;
}
else r=mid-1;
}
printf("%d",ans);
return 0;
}
4)快读
int read(){//我喜欢快读
int num = 0;
char c;
bool flag = false;
while ((c = getchar()) == ' ' || c == '\n' || c == '\r');
if (c == '-') flag = true;
else
num = c - '0';
while (isdigit(c = getchar()))
num = num * 10 + c - '0';
return (flag ? -1 : 1) * num;
}
5)reverse 翻转函数
STL里面的反转字符串函数 \color{red}\text{reverse()}reverse()
其格式是: reverse(reverse( 数组名 .begin().begin() ,, 数组名 .end().end() ););
洛谷 P5705 【深基2.例7】数字反转
#include<bits/stdc++.h> //文件头
using namespace std;
string a; //定义字符串
int main()
{
cin>>a; //输入
reverse(a.begin(),a.end()); //反转
cout<<a; //输出
return 0; //养成好习惯
}
6)快排模板
void qasort(int l,int r)
{
int i,j,mid,p;
i=l;j=r;
mid=a[(l+r)/2];
do
{
while (a[i]<mid) i++;
while (a[j]>mid) j--;
if(i<=j)
{
p=a[i];a[i]=a[j];a[j]=p;
i++;j--;
}
}while(i<=j);
if(l<j) qasort(l,j);
if(i<r) qasort(i,r);
}
7)求x的y次方 pow(x,y);
包含在头文件math.h之中
8)cin读入一行字符串(且要保存空格)
getline(cin, s);
9)裴蜀定理
gcd(a,b)=ax+by;(存在整数x,y使等式成立,x,y可以是复数)
该表达式可以拓展到无限,gcd(gcd(a,b),c)=ax+by+cz等等;
10)不尽则保留n位小数
题目大意:输入a,b;计算对角线长度与a+b的差,最多保留9位小数。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a,b;
double x;
scanf("%d%d",&a,&b);
x=sqrt(a*a+b*b);
cout<<setprecision(9)<<a+b-x;
return 0;
}
setprecision(n);
11)加快cin输入输出流
ios::sync_with_stdio(false);cin.tie(0);
据说可以达到 scanf 的速度。
12)比较两个字符串
str1.compare(str2);
如果相等则该函数输出为0,不等则输出为-1。
13)数学复制矩阵
/*最大公约数*/inline int gcd(int a, int b) { return b > 0 ? gcd(b, a%b) : a; }
/*最小公倍数*/inline int lcm(int a, int b) { return a * b / gcd(a, b); }
/*平方数*/inline int qpow(int a, int n) { int ans = 1; while (n) { if (n & 1) { ans *= a; }a *= a; n >>= 1; }return ans; }
/*平方数(结果除模)**/inline int _qpow(int a, int n) { int ans = 1; while (n) { if (n & 1) { ans *= a % mod; ans %= mod; }a *= a; a %= mod; n >>= 1; }return ans % mod; }
///*快读 */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 = 10 * x + ch - '0'; ch = getchar(); } return x * f; }
14)快速幂
long long normalPower(long long base, long long power) {
long long result = 1;
for (int i = 1; i <= power; i++) {
result = result * base;
result = result % 1000;
}
return result % 1000;
}
long long int Pow(long long int a, long long int b, long long int c)
{
if(a==0)
return 0;
long long int r = 1, base = a;
while(b)
{
if(b&1)
{
r = (r * base) % c;
}
base = (base * base) % c;
b>>=1;
}
return r;
}
15)s.substr()
0. 用途:一种构造string的方法
1. 形式:s.substr(pos, n)
2. 解释:返回一个string,包含s中从pos开始的n个字符的拷贝(pos的默认值是0,n的默认值是s.size() - pos,即不加参数会默认拷贝整个s)
3. 补充:若pos的值超过了string的大小,则substr函数会抛出一个out_of_range异常;若pos+n的值超过了string的大小,则substr会调整n的值,只拷贝到string的末尾
#include<string>
#include<iostream>
using namespace std;
int main()
{
string s("12345asdf");
string a = s.substr(5,0);
cout << a << endl;
}
/*output: 12345*/
16 )string find()函数
#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
/* stage 1 */
//string中find()返回值是字母在母串中的位置(下标记录),如果没有找到,那么会返回一个特别的标记npos。(返回值可以看成是一个int型的数)
//find函数返回类型 size_type
string s("abcdefghijabcde");
string::size_type position;
//find 函数 返回jk 在s 中的下标位置
position = s.find("bc");
if (position != s.npos) //如果没找到,返回一个特别的标志c++中用npos表示
{
printf("position is : %d\n" ,position);
}
else
{
printf("Not found the flag\n");
}
/* stage 2 */
//返回子串出现在母串中的首次出现的位置,和最后一次出现的位置
string flag="c";
position = s.find_first_of(flag);
printf("s.find_first_of(flag) is :%d\n",position);
position = s.find_last_of(flag);
printf("s.find_last_of(flag) is :%d\n",position);
/* stage 3 */
//查找某一给定位置后的子串的位置
//从字符串s 下标5开始,查找字符串b ,返回b 在s 中的下标
position=s.find("b",5);
cout<<"s.find(b,5) is : "<<position<<endl;
}
17)高效位运算函数高效位运算 __builtin_函数
•__builtin_ffs (unsigned int x)
返回x的最后一位1的是从后向前第几位,比如7368(1110011001000)返回4。
•__builtin_clz (unsigned int x)
返回前导的0的个数。
•__builtin_ctz (unsigned int x)
返回后面的0个个数,和__builtin_clz相对。
•__builtin_popcount (unsigned int x)
返回二进制表示中1的个数。
•__builtin_parity (unsigned int x)
返回x的奇偶校验位,也就是x的1的个数模2的结果。
此外,这些函数都有相应的usigned long和usigned long long版本,
只需要在函数名后面加上l或ll就可以了,比如__builtin_clzll。
18)to_string
#include <iostream>
#include <string>
using namespace std;
int main()
{
string pi = "pi is " + std::to_string(3.1415926);
string perfect = to_string(1 + 2 + 4 + 7 + 14) + " is a perfect number";
cout << pi << '\n';
cout << perfect << '\n';
system("pause");
return 0;
}
输出
pi is 3.141593
28 is a perfect number
请按任意键继续. . .
19)1ll
ong long ANS=1LL*num*((1LL)*n*(n-1))/2; ,其中用了1LL;LL其实代表long long,*1LL是为了在计算时,把int类型的变量转化为long long,然后再赋值给long long类型的变量。代码中的ANS的定义为: long long ANS
ANS是long long类型的, ANS=1LL*num*((1LL)*n*(n-1))/2;
不至于后面计算溢出,*1LL 之后类型就转换为long long, num,n定义的是int类型的。
这篇博客总结了C++编程中的实用技巧和算法应用,包括next_permutation、nth_element函数,二分查找思路,快读,字符串翻转,快速排序模板,幂运算,输入输出优化,以及位运算优化等,结合洛谷例题进行讲解。

被折叠的 条评论
为什么被折叠?



