修改code completion快捷键位CTRL+ENTER,帮助提示函数名称

修改命令行提示符的属性,开启快速编辑模式,方便调试

添加c++11语言标准支持

开启代码调试功能

对输入的字符串进行切割时,可以使用scanf按照指定格式分别输入达到切割效果,比如:

//对于这样的输入
3-10 99
11-5 87
102-1 0
//对于这种格式不绝对统一的字符串,可以自己构造相应的scanf分割对应的数据
scanf("%d-%d %d", &t, &num, &score);

对于需要进行除法运算的变量,并且有精确度要求的时候,可以这样

double grade =0;
//其中fullscore数组为int类型,在*1.0小数之后,自动转换为浮点型
grade += fullscore[j] * 1.0 / 2;
//或者这样强转
grade += (double)fullscore[j]/2;

如果在getline读取行之前还有其它的输入字符(不管是字符还是整数),则需要保证在调用getline函数之前,使用getchar()函数读取一次回车符,然后再调用

#include<iostream>
using namespace std;
int main() {
char n;
scanf("%c",&n);
getchar();
string str;
getline(cin,str);
cout<<str;
}

散列表的应用:在需要进行遍历数组内容,判断某一个元素是否存在时,可以使用一个大数组,初始化为0,录入数据时,相应数据(把下标看成数据)的内容修改为1,这样判断的时候直接判断a[element]==1即可,其中element为录入的数据。这样就把O(n)级别的时间复杂度降到了O(1)

atoi&stoi(stol)&strtol区别

参考:https://www.ibm.com/developerworks/community/blogs/12bb75c9-dfec-42f5-8b55-b669cc56ad76/entry/c_11%25e4%25b8%25ad%25e7%259a%2584string_atoi_itoa?lang=en

即使不记得也没关系,只要记住以下用法即可

//数字型变量转字符串
to_string();//c++全局函数 //字符串转数字
stoi();//to int
stol();//to long
stof();//to float
//都需要导入#include <string>

四舍五入,可以先double +0.5然后转int取整数部分,也可以用cmath的函数round()

数组,字符串或其它常用stl容器大规模清零或者填充数据可以使用fill()函数

// fill algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::fill
#include <vector> // std::vector int main () {
std::vector<int> myvector (8); // myvector: 0 0 0 0 0 0 0 0 std::fill (myvector.begin(),myvector.begin()+4,5); // myvector: 5 5 5 5 0 0 0 0
std::fill (myvector.begin()+3,myvector.end()-2,8); // myvector: 5 5 5 8 8 8 0 0 std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n'; return 0;
}

output

myvector contains: 5 5 5 8 8 8 0 0

将十进制a转换为b进制数,当a不为0时,将a%b从后往前倒序保存下来,每次保存后将a/b。这样倒序保存的数就是十进制a在b进制下的结果。

进制互转代码参考如下

#include<iostream>
#include<cstdlib>
using namespace std;
int main(){
//把8进制的17转化为10进制打印输出
string str = "17";
char *tmp ;
long result = strtol(str.c_str(),&tmp,8);
cout<<result;
return 0;
} #include<iostream>
#include<algorithm>
using namespace std;
//digital为10进制数,r为需要转换的目标进制,返回目标进制数
string dtox(int digital,int r){
string result="";
const char s[37]="0123456789abcdefghijklmnopqrstuvwxyz";
if(digital==0){
return "0";
}
while(digital!=0){
int tmp =digital%r;
result+=s[tmp];
digital/=r;
}
reverse(result.begin(),result.end());
return result;
}
int main(){
cout<<"十进制10转为16进制结果:"<<dtox(10,16)<<endl;
cout<<"十进制10转为8进制结果:"<<dtox(10,8)<<endl;
cout<<"十进制10转为2进制结果:"<<dtox(10,2)<<endl;
cout<<"十进制10转为10进制结果:"<<dtox(10,10)<<endl;
}

尽量使用c++的string类

读取整行的代码如下

string str;
getline(cin,str);//该函数在std标准库中,不需要引入string头文件

c++的string类可以转化为c的字符数组,str.c_str();

最大公约数和最小公倍数求解

int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
int lcm(int a,int b){
return a*b/gcd(a,b);
}

对于一些可以事先进行预处理然后用散列表来求解的问题,可以大大减少时间复杂度。比如一个需要大量查询斐波那契数列的问题中,我们可以事先把前N个斐波那契数列求解出来然后放到散列表中进行保存,之后的查询就都是O(1)的时间复杂度。

▲多利用位运算来求解交集,并集,差集,可以大大减少时间复杂度,降低编码难度。

素数的判断

bool isPrime(int n){
if(n <= 1) return false;
int sqr = (int)sqrt(1.0*n);
for(int i = 2;i<=sqr; i++){
if(n%i==0) return false;
}
return true;
}

常用C++ STL容器

C++ container

algorithm头文件常用函数

algorithm

  • max
  • min
  • abs
  • swap
  • reverse
  • is_permutation
  • next_permutation
  • prev_permutation
  • fill
  • sort
  • lower_bound
  • upper_bound

大数组必须定义为全局变量

字符数组要多开一个单位

string.find()返回的是下标的值,没有找到用==string::npos

dev c++调试代码时,查看vector容器的内容

同时存在边权和点权的最短路径问题,求最短路径条数以及最大点权和、打印最短路径?

  • 用一遍Dijkstra算法即可
  • dis[i]表示从出发点到i结点最短路径的路径长度
  • num[i]表示从出发点到i结点最短路径的条数
  • w[i]表示从出发点到i结点点权的数目之和
  • path[i]表示从出发点到i结点的前驱结点,利用栈(或者递归)打印路径即可

图的初始化

  • 如果是无向图,需要注意初始化边的时候,是有两条边的,不能漏掉了

  • 没有边的情况(包括两种情况,1.顶点v,w之间不存在边,2.顶点v本身没有到达自己的边),初始化为0,如果是初始化为-1,则判断边是否存在的时候需要注意G[i][j]<0而不是直接if(G[i][j]),这两种判断一个是判断0,一个是判断<0

  • 图的初始化,可以用fill函数,具体用法可以参考如下

    //必须添加algorithm头文件
    #include<algorithm> //在内存地址区间[first,last)范围内,填充x
    fill(first,last,x); //但是特别注意二维数组的填充
    int arr[2][2];
    fill(arr[0],arr[0]+4,0);
    /*
    这里需要注意的是,arr[0]表示的才是整个二维数组的起始地址,而不是arr,另外,这个区间是左闭右开区间!!!
    */

    不仅是图的初始化, 其它的辅助数组也可以用fill函数初始化,比如说path数组(用于记录顶点w的前驱顶点,打印最短路径),dist数组(用于记录出发点到顶点w的最短路径),num数组(用于记录从出发点到顶点w的最短路径条数),w数组(用于记录从出发点到顶点w的点权之和)等。

  • 在真正进行Dijkstra算法之前,先检查下面这些数据是否都已经初始化好了

    1.初始化图
    2.初始化路径
    3.初始化距离
    4.初始化收录情况
    5.初始化点
    6.初始化出发点,以及出发点的邻接点的路径和距离信息

最短路径扩展问题

  • 要求数最短路径有多少条

    • count[s] = 1;
    • 如果找到更短路:count[W]=count[V];
    • 如果找到等长路:count[W]+=count[V];
  • 要求边数最少的最短路

    • count[s] = 0;
    • 如果找到更短路:count[W]=count[V]+1;
    • 如果找到等长路:count[W]=count[V]+1;
  • 存在点权

    比如救火问题,多条最短路径,选择点权最大的那条

    for(int i = 0; i < n; i++) {
    int u = -1, minn = inf;
    for(int j = 0; j < n; j++) {
    if(visit[j] == false && dis[j] < minn) {
    u = j;
    minn = dis[j];
    }
    }
    if(u == -1) break;
    visit[u] = true;
    for(int v = 0; v < n; v++) {
    if(visit[v] == false && e[u][v] != inf) {
    if(dis[u] + e[u][v] < dis[v]) {
    dis[v] = dis[u] + e[u][v];
    num[v] = num[u];
    w[v] = w[u] + weight[v];
    } else if(dis[u] + e[u][v] == dis[v]) {
    num[v] = num[v] + num[u];
    if(w[u] + weight[v] > w[v])
    w[v] = w[u] + weight[v];
    }
    }
    }
    }
  • 边权不唯一

    比如旅游规划问题,存在多条最短路径时,选择花费最少的

    void Dijkstra( Vertex s ) {
    while (1) {
    V = 未收录顶点中dist最小者;
    if ( 这样的V不存在)
    break;
    collected[V] = true;
    for ( V 的每个邻接点W )
    if ( collected[W] == false )
    if ( dist[V]+E<V,W> < dist[W] ) {
    dist[W] = dist[V] + E<V,W> ;
    path[W] = V;
    cost[W] = cost[V] + C<V,W> ;
    } else if ( (dist[V]+E<V,W> == dist[W])
    && (cost[V]+C<V,W> < cost[W]) ) {
    cost[W] = cost[V] + C<V,W> ;
    path[W] = V;
    }
    }
    }

algorithm常用函数补充

所有的range都是左闭右开区间

//判断range1是否为range2(长度length2>=length1)的子序列,可以完全相等

is_permutation(first1,last1,first2);

//查找range2在range1中的位置

search(first1,last1,first2,last2);

//交换a和b的值

swap(a,b);

//填充range

fill(first,last,value);

//reverse反转一个range

reverse(first,last);

//判断range是否有序【升序asc】

is_sorted(first,last);

//获取从那个位置开始无序

is_sorted_until(foo.begin(),foo.end());

//一个有序range插入新元素x的最小插入位置

lower_bound (v.begin(), v.end(), 20);

//一个有序range插入新元素x的最大插入位置

upper_bound (v.begin(), v.end(), 20);

//合并两个range到一个新容器中

std::merge (first,first+5,second,second+5,v.begin());

//获取min

std::min(1,2)

//获取max

std::max(1,2)

//获取min_element

std::cout << "The smallest element is " << *std::min_element(myints,myints+7) << '\n';

//获取max_element

std::cout << "The largest element is " << *std::max_element(myints,myints+7) << '\n';

//获取一个range的一个序列

int main () {

int myints[] = {1,2,3};

std::sort (myints,myints+3);

std::cout << "The 3! possible permutations with 3 elements:\n";

do {

std::cout << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n';

} while ( std::next_permutation(myints,myints+3) );//对应的就是更大的序列

std::cout << "After loop: " << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n';

return 0;

}

输出结果

The 3! possible permutations with 3 elements:

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

After loop: 1 2 3

类似的还有

std::prev_permutation(myints,myints+3) 返回一个bool

true if the function could rearrange the object as a lexicographicaly smaller permutation(字典序更小的子序列).

Otherwise, the function returns false to indicate that the arrangement is not less than the previous, but the largest possible (sorted in descending order).

开考前,可以先用记事本把一些常用的头文件写下来

注意求平均值的时候是否需要四舍五入,如果需要+0.5即可

排名问题,如果两个人分数一样,那么排名也是一样的,比如

第一种情况:

1,1,1,4,5,6

stu[0].rank[flag] = 1;
for(int i = 1; i < n; i++) {
stu[i].rank[flag] = i + 1;
if(stu[i].score[flag] == stu[i-1].score[flag])
stu[i].rank[flag] = stu[i-1].rank[flag];
}

第二种情况:

1,2,3,4,5

这种比较简单,可以直接使用for循环,或者while循环,临时变量每次自增1即可

通常都是第一种情况,如果是第二种情况的话,很可能会附加排序字段

fill函数对于重置exist,flag,visit等类型的数组很方便,也省时间,一般只在fill函数无法满足要求时才考虑使用遍历重置数组

求图的连通分量的个数

void dfs(int node) {
visit[node] = true;
for(int i = 1; i <= n; i++) {
if(visit[i] == false && v[node][i] == 1)
dfs(i);
}
} int cnt = 0;
for(int j = 1; j <= n; j++) {
if(visit[j] == false) {
dfs(j);
cnt++;
}
}

还可以用并查集来求连通分量

中序和后序转先序

#include <cstdio>
using namespace std;
int post[] = {3, 4, 2, 6, 5, 1};
int in[] = {3, 2, 4, 1, 6, 5};
void pre(int root, int start, int end) {
if(start > end) return ;
int i = start;
while(i < end && in[i] != post[root]) i++;
printf("%d ", post[root]);
pre(root - 1 - end + i, start, i - 1);
pre(root - 1, i + 1, end);
} int main() {
pre(5, 0, 5);
return 0;
}

循环输入

#include<iostream>
using namespace std;
int main(){
//cin循环输入测试
int a;
//只要输入的整数a不等于9,循环就会一直执行,直到输入9
while(cin>>a,a!=9){
printf("%d\n",a);
}
return 0;
}

如果要在遇到换行符时退出循环,可以使用getchar()函数来判断

#include<iostream>
using namespace std;
int main() {
//cin循环输入测试
string tkey;
while(cin >> tkey) {
cout<<tkey<<endl;
char c = getchar();
if(c == '\n') break;
}
return 0;
}

【持续更新】【pat】pat刷题技巧记录的更多相关文章

  1. ( 译、持续更新 ) JavaScript 上分小技巧(四)

    后续如有内容,本篇将会照常更新并排满15个知识点,以下是其他几篇译文的地址: 第一篇地址:( 译.持续更新 ) JavaScript 上分小技巧(一) 第二篇地址:( 译.持续更新 ) JavaScr ...

  2. ( 译、持续更新 ) JavaScript 上分小技巧(三)

    最近家里杂事较多,自学时间实在少的可怜,所以都在空闲时间看看老外写的内容,学习之外顺便翻译分享~等学习的时间充足些再写写自己的一些学习内容和知识点分析(最近有在接触的:复习(C#,SQL).(学习)T ...

  3. ( 译、持续更新 ) JavaScript 上分小技巧(二)

    考虑到文章过长,不便于阅读,这里分出第二篇,如有后续,每15个知识点分为一篇... 第一篇地址:( 译.持续更新 ) JavaScript 上分小技巧(一) 第三篇地址:( 译.持续更新 ) Java ...

  4. ( 译、持续更新 ) JavaScript 上分小技巧(一)

    感谢好友破狼提供的这篇好文章,也感谢写这些知识点的作者们和将他们整理到一起的作者.这是github上的一篇文章,在这里本兽也就只做翻译,由于本兽英语水平和编程能力都不咋地,如有不好的地方也请多理解体谅 ...

  5. PAT甲级训练刷题代码记录

    刷题链接:https://www.patest.cn/contests/pat-a-practise 1001 #include <iostream> #include <stdio ...

  6. 一些有意思的面试题(持续更新) .C语言编程技巧札记

    一些有意思的面试题(持续更新) http://blog.csdn.net/wangyuling1234567890/article/details/38565239 C语言编程技巧札记 http:// ...

  7. noip2012~2015刷题小记录

    2012d1t1 密码 模拟题 #include<cstdio> #include<cstdlib> #include<cstring> #include<c ...

  8. 【长期更新】Leetcode刷题心得与思考

    1.递归与动态规划的思考 Leetcode第95题 递归问题最重要的问题是想明白函数的作用是什么? 这个例子中函数的返回值就是给定a-b这个区间的数字,返回它所有可能的Tree,此时你不需要明白具体怎 ...

  9. Datagrip 快捷键和常用插件持续更新一集一些使用技巧

    快捷键 Ctrl+Enter:执行选中的SQL语句 Ctrl+Shift+左右箭头:调整列宽度(选中行,可以调整所有列的宽度) Ctrl+N / 双击Shift :全局搜索,点击可直接进入表 Ctrl ...

随机推荐

  1. 同一台机上配置多个redis服务

    "D:\Program Files\Redis\redis-server.exe" --service-run F:Redis2\redis.windows-service6380 ...

  2. halcon小结

    持更 应用范围 (罗列自官方帮助文档,以后有空了按照需求展开叙述) 1. 安全系统 2. 表面检测 3. 定位 4. 二维测量比较 5. 二维码识别 6. 二维位置定位 7. 二维物体识别 8. 光学 ...

  3. 8.Nginx基本概述

    io网络模型介绍 1.介绍Nginx Nginx是一个高性能的HTTP和反向代理web服务器 2.常见的Web服务器 httpd Nginx Tengine OpenResty 3.介绍Nginx应用 ...

  4. 7.HTTP协议

    1.什么是url? 1.1 URL是统一资源定位符,表示的是一个资源,(图片 文字 视频 音频 等等) 单个资源介绍--图片 那URL的组成部分是由协议, 域名:端口, 路径和文件名 1.2 url组 ...

  5. 从C++到C++/CLI

    本文转载于:https://www.cnblogs.com/feisky/archive/2009/11/22/1607999.html 刘未鹏(pongba) /文 看起来只是在C++后面多写了一个 ...

  6. Kafka 权威指南阅读笔记(第三章,第四章)

    Kafka 第三章,第四章阅读笔记 Kafka 发送消息有三种方式:不关心结果的,同步方式,异步方式. Kafka 的异常主要有两类:一种是可重试异常,一种是无需重试异常. 生产者的配置: acks ...

  7. 组合+封装+property+多态+鸭子类型(day21)

    目录 昨日回顾 继承 什么是继承 继承的目的 什么是抽象 继承背景下,对象属性的查找顺序 派生 什么是派生 子类派生出新的属性,重用父类的属性 新式类和经典类 钻石继承的继承顺序 今日内容 一.组合 ...

  8. Veins(车载通信仿真框架)入门教程(三)——多跳路由实现指导

    Veins(车载通信仿真框架)入门教程(三)——多跳路由实现指导 Veins(车载通信仿真框架)入门教程(三)——多跳路由实现指导 必要的message类实现 从下面开始是在veins/src/vei ...

  9. stream流篇

    流是C#中比较重要的一个概念,很多关键技术都需要用到流.何为流呢?可以理解流为江河中水的流动,不过C#中则为信息流,我们可以把信息写入流,也可以读出.比如以文件读写操作为例,首先以某种方式(如只读)打 ...

  10. fenby C语言 P14

    打赌 条件运算符 (表达式?值1:值2) 赌注内容 奖励 奖励 y=(x==2?100:50): x==2,那么y=100 x!=2,那么y=50 #include int main() { int ...