【1】头文件下把using namespace std;改成using std::max_element;,代码里可以用*max_element(arr, arr + 1500)求数组最大值。
【2】除了set外,map也是可以用map<int,int>::iterator it=mp.lower_bound(p);,地址转换可以直接--it。两个参数是it->first和it->second。
【3】以后可以把优先队列写成priority_queue<node,vector<node>,cmp> q; 在main函数外加上:
struct cmp{
bool operator()(const node &t1,const node &t2){
return t1<t2; //从大到小,与数组规则相反
}
};
【4】如果碰到了只查询一次的线段树那么可以用差分来做。比如求平行线段重叠的最大值,完全可以只关注所有线段的始末点。起始点加值,末尾点减值,然后累加。
【5】碰到有什么思路想不出或者诡异的时候,优先想到用队列。
【6】判断一下是否存在环:拓扑排序(即队列清空后还有数字没有进过队列),并查集,Floyd。
【7】如果某一块的值有很多种可能,且可以互相覆盖,那么把最终出现的值与所有可能值之间连一条有向边,指向可能值。
【8】unsigned long long超过范围也不会像int一样变成负数,可以在需要哈希的时候使用(因为每次进位必须乘一个较大的素数,所以值会超级大,但是用ull存没问题)。
【9】unique不要使用在类型是node的数组。
【10】在r之前的数量-在l之前的数量 upper_bound(A.begin(),A.end(),r) - lower_bound(A.begin(),A.end(),l)
【11】不要写成:for(int i=0;i<strlen(str);++i){ ,PAT就超时了!
int len=strlen(str);
for(int i=0;i<len;++i){ 这样就过了!
【12】 isalpha isdigit islower tolower isupper toupper
【13】
//char* cp="ABCDE"; char cp[10]="ABCDE"; string s(cp+1, cp+5); // "BCDE" string s2(s.begin()+1, s.end()-1); // "CD"
//把整数123 打印成一个字符串保存在s 中。
sprintf(s, "%d", 123); //产生"123"
void main()
{
// int 转 string
stringstream ss;
int n = 123;
string str;
ss<<n;
ss>>str;
// string 转 int
str = "456";
n = atoi(str.c_str());
}
规范代码格式.cpp
#include<bits/stdc++.h>
using namespace std;
bool isChines(const std::string &inStr){
unsigned char *str=(unsigned char *)inStr.c_str();
size_t length=inStr.length();
for (size_t i=0;i< length;++i){
if (str[i]>160){
return true;
}
}
return false;
}
int main(){
freopen("1.txt","w",stdout);
string x,y;
int ok=0;
while(getline(cin,x)){
int i;
for(i=0;i<x.length();++i){
if(x[i]!=' '&&x[i]!='\t')
break;
}
if(i==x.length())continue;
if(x[i]=='{'){
cout<<x[i]<<y;
y="";
continue;
}
else{
if(ok==1){
// if(x.length()>0&&isChines(x.substr(0,1)))
// cout<<endl;
cout<<y<<endl;
}
else
ok=1;
}
y="";
for(int i=0;i<x.length();++i){
if(i<x.length()-1&&x[i]=='/'&&x[i+1]=='/'){
y=x.substr(i,x.length()-i);
break;
}
if(i<x.length()-2&&x[i]==' '&&(x[i+1]=='('||x[i+1]=='+'||x[i+1]=='-'||x[i+1]=='*'||x[i+1]=='/'
||x[i+1]=='%'||x[i+1]=='='||x[i+1]=='>'||x[i+1]=='<'||x[i+1]=='^'||x[i+1]=='|'||x[i+1]=='&'
||x[i+1]=='('||x[i+1]==')'||x[i+1]==',')&&x[i+2]==' '){
cout<<x[i+1];
i+=2;
}
else if(i<x.length()-2&&x[i]==')'&&x[i+1]==' '&&x[i+2]=='{'){
cout<<x[i]<<x[i+2];
i+=2;
}
else if(i<x.length()-1&&(x[i]==','||x[i]==';')&&x[i+1]==' '){
cout<<x[i];
i+=1;
}
else if(i<x.length()-3&&x[i]==' '&&(x.substr(i+1,2)=="=="||x.substr(i+1,2)==">="||x.substr(i+1,2)==">>"||x.substr(i+1,2)=="<<"||
x.substr(i+1,2)=="<="||x.substr(i+1,2)=="+="||x.substr(i+1,2)=="-="||x.substr(i+1,2)=="*="||x.substr(i+1,2)=="||"||x.substr(i+1,2)=="&&")&&x[i+3]==' '){
cout<<x.substr(i+1,2);
i+=3;
}
else
cout<<x[i];
}
}
cout<<y;
}
改变运行终端界面:void InitMyset(){
system("mode con: cols=40 lines=40");
system("titleXXXXXXXXXXXXXX");
system("color 80");
};
sum=0;
for(i=1;i<=n;i++)
{
scanf("%I64d",&f[i]);
l[i]=r[i]=i; //初始i点的左边界和右边界都是i。
}
f[0]=f[n+1]=-1;
for(i=1;i<=n;i++)
{ //预处理左边界 !
while(f[i]<=f[l[i]-1])
l[i]=l[l[i]-1];
}
for(i=n;i>=1;i--)
{ //预处理右边界 !
while(f[i]<=f[r[i]+1])
r[i]=r[r[i]+1];
}
for(i=1;i<=n;i++) //遍历更新最大值
if(f[i]*(r[i]-l[i]+1)>sum)
sum=f[i]*(r[i]-l[i]+1);
printf("%I64d\n",sum);
for(int i=1;i<=n;++i){
cin>>x[i];
l[i]=i;
r[i]=i;
}
for(int i=0;i<=n;++i)
while(x[i]<=x[l[i]-1]) l[i]=l[i]-1;
for(int i=n;i>=1;--i)
while(x[i]<=x[r[i]+1]) r[i]=r[i]+1;
【数论补充】
gcd(a,b)=gcd(b,a%b)=gcd(a+mb,b)
最长路的求法类似最短路,只不过每个点向拓展的时候都要先更新一遍dp[i],拓展完最后要把该点的vis值改回零