珍爱生命,远离ACM
自测数据三要素
昨晚题目自己优先测试数据 减少提交次数
- 边界数据(极大/极小)
- 重复数据
- 容易漏掉得数据
1.数组范围
一般我们记住在开数组时一定要比规定的范围多5-10个空间.否则你就会幸运踩坑
例如:限定有10^4个数据
那么 开设数组最好为 type [10005] 有效防止溢出或者边界问题
2.字符串空行问题
当要求我们输入两个字符串时,有时老奸巨猾的出题人会由于某种特殊情况将第一行设置为空行,这是你再想利用cin/scanf给两个字符串赋值时就会出现问题,因为他没有空行过滤所以会一直卡再输入那里,遇到这种情况请使用getline(cin,str)!!!.
三目运算符
如果只涉及到一重if ... else ...
尽可能的用三目运算符表示
C++中将string快速转为int
stoi(string) **atoi(const char*)**
atoi()的参数是char类型的数组,因此对于一个字符串我们需要先将其利用c_str将该方法转为char 类型的,而stoi()参数是从 const string 类型不需要转换
例如:
cout<< atoi(string::c_str()) <<endl; cout<< stoi(string) <<endl;
stoi()会做边界检查,默认实在int 范围内,如果超出会runtime error
atoi()如果超出范围只会输出上界和下界
巨坑之精度转换问题
void func() { 这里是一个巨坑 还得我两个测试点没过 二刷才发现 关于精度转换问题 不强制转换情况下从int 转换double或者float类型的数据是最好乘上一个 * 1.0!!! double ans1 = (pronone*100.0) / n ; double ans2 = (none * 100.0) / n ; printf("%.1f", ans1); cout << "% "; printf("%.1f", ans2); cout << "%"; }
map 映射 容器
c++ 中可以使用map映射一个容器类型
map<string,vector<node> > v; 存储 : v[string].push_back(结构体类型); for (int i = 1; i < n; i++) { if (data[i].name == data[i - 1].name && data[i - 1].status == 1 && data[i].status == 0) { custom[data[i - 1].name].push_back(data[i - 1]); custom[data[i].name].push_back(data[i]); } }
判断闰年模板
bool check(int year) { if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))return 1; else return 0; }
(数学问题)
实际上考察的数学问题,要注意分析十属题目先观察数据是否含有某种规律,在排版数据的时候注意多种方式不要拘泥于一种,更容易发现规律
线性筛素数模板
PAT题目中对于素数的筛选十分常见 需要熟记模板
bool vis[1000000]; int n,cnt = 0,prime[100000]; void shai() { vis[1] = 1; //注意这里是 i 小于 n for(int i = 2;i <= n; i++){ if(!vis[i])prime[++cnt] = i; for(int j = 1; j <=cnt && i * prime[j] <= n; j++ ){ vis[i * prime[j]] = 1; //如果标记位1说明不是素数 if(i % prime[j] == 0)break; } } }
bool isprime(int n) { int t = sqrt(n); for(int i = 2; i <= t;i++) if(t % i == 0)return false; return true; }
注意对某些题目输出 0 数据的检测
例如PAT 1010一元多项式求导问题
if(flag == 0)cout << "0 0"<< endl;
对于条件较多的模拟题一定要先罗列出条件再设计代码
在对变量的命名的时候一定要避开关键字
如: hash map next rank 等
将string类性能转换为 char类型的数组的方法:string.c_str()
常用的几个处理字符串时的内置函数
isalnum() : 判断一个字符是否为字符或者数字
isalpha() : 判断一个字符是否为字母
isupper() : 判断一个字母是否为大写
islower() : 判断一个字母是否为小写
tolower() : 返回一个字母的小写形式
toupper() : 返回一个字母的大写形式
isdigit() : 判断一个字符是否为数字
string.substr(起始位置,截取字串的长度);
string.find(字符串) 成功返回位置索引 失败返回string::npos
string.append(追加长度,追加字符必须是char类型)
a.compare(字符串b) : 比较两个字符串的大小 a > b 返回 1 ,a
< b 返回 -1 相等返回 0
## 如果遇到大量的输入输出不需要思考直接使用scanf 和 printf 大概会缩短一倍的时间
## 注意看题目给定的数据范围
## 段错误一般属于数组越界,内存泄漏,或者溢出问题,优先考虑某处的范围限定是否合理观察是运行时存在内存泄漏
## 变量隔离: 要观察无关的变量的生命周期,判断其是是否会影响之后的代码块
## gcd求最大公约数模板C++ int gcd(int a,int b){ return b == 0 ? a : gcd(b , a % b); }
## 在处理字符串输入的时候要考虑是否应该用getline(cin,s);
如果需要用getline 进行输入要确保之前没有输入操作 或者 有一个getchar() 来吸收上一次产生的回车 否则会影响后序的操作
cin会过滤空格字符,想要处理带有空格的字符还是要用getchar()
关于sscanf() 和 ssprintf() 的小技巧
#include <iostream> #include <algorithm> #include <string.h> #include <cstdio> using namespace std; int main() { char str[256] = { 0 }; int data = 1024; //将data转换为字符串 sprintf(str,"%d",data); puts(str); //获取data的十六进制 sprintf(str,"0x%X",data); puts(str); //获取data的八进制 sprintf(str,"0%o",data); puts(str); const char *s1 = "Hello"; const char *s2 = "World"; //连接字符串s1和s2 sprintf(str,"%s %s",s1,s2); puts(str); int year,day,a; char month[10],weekday[10],total[100]; strcpy(total,"sunday June 15 2018"); a = sscanf(total,"%s %s %d %d",weekday,month,&day,&year); //将total里面的数据从左取出来之后,并存储到相应类型的变量中 //变量使用的是地址,weekday和month使用的是字符数组首地址, //day和year由于是int类型,所以需要加上取地址符 printf("%d\n",a);//输出返回值 printf("%s %s %d %d\n",weekday,month,day,year); system("pause"); return 0; }
如何判断一个数是否为回文数
快速判断
bool check(int x) { int m = 0, t = x; while(t > 0) { m = m * 10 + t % 10; t /= 10; } return m == x; }
判断闰年模板
bool check(int year) { if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))return 1; else return 0; }
来源:https://www.cnblogs.com/wlw-x/p/12367842.html