天梯赛L1一共有64个题,前几天爆肝完了,特别适合初级的OJ选手,有难题也有很容易的题,以下为个人总结的一些小经验与技巧。(尤其是字符串的处理)
任何题都适用的
- 头文件用#include<bits/stdc++.h> 可以代替几乎能用到的所有头文件,一行搞定所有。(记得加一句using namespace std;)
- 如果题目里面给定了最大数据量,比如这题:题目链接题目说了给出的N<=100。这个题一般的解法是写一个struct,然后生成一个装struct的数组,这时候这个数组的容量最好开105或者110!避免有一个样例或者两个样例过不去。同理,最好最大的数组比题目给的最大输入大一点
跟数学有关的
素数类
因为math里面没有求素数的函数,所以需要自己写~
求素数标准模板:
bool isprime(int n){
if(n<=1) return false;
for(int i=2;i<=(int)sqrt(1.0*n);i++){
if(n%i==0)
return false;
}
return true;
}
关于素数判断之类的题,特别要注意:1不是素数,2是素数!一定要记得单独讨论,避免样例过不去。
指数类
指数没啥坑点,直接用pow(n,m)就可以求指数啦~ 算出来的是nm。
阶乘、排列组合类
求n!太容易啦,这里就不赘述了。这里讲一个问题:求n!中有多少个质因子p
int cal(int n,int p){
int ans = 0;
while(n){
ans += n / p; //累加n/p^k
n /= p; //相当于分母多乘一个p
}
return ans;
}
这个方法可以很快求出n!的末尾有多少个零。
求n中选m个的排列组合:
long long C(long long n, long long m){
long long ans = 1;
for(long long i = 1; i <= m;i++){
ans = ans * (n - m + i) / i; //注意要先乘再除
}
}
这个可以背一下,需要用的时候直接套。
求公因子类(gcd)
求公因子的模板:
int gcd(int a,int b){
if(b==0) return a;
return gcd(b,a%b);
}
写多了就记得了。
分数的加减类
做第九题的时候就很头疼,虽然是最简单的分数问题。
以这个题为例,我用了两个变量当做分子和分母,分别初始化为int a=0;int b=1;
分数相加:(以"%d/%d",&c,&d的形式读入)
就相当于两个分数直接相加,分母相乘,分子乘以分母。
所以相加可以用代码描述为
a = a*c + b*d
b = b*d
这时的a b为相加以后的和。
约分问题:用上述的gcd找到分子分母的最大公因数,然后相处即完成约分。
int n = gcd(a,b);
a /= n;
b /= n;
这样就完成啦相加和约分,可以用这种方法一次读入一个分数就加到最开始的分数上,每次相加完都要约分~
字符串读取类
字符串的读取可太重要了吧,本文主要解决题目给的输入的读取问题,困扰了我很久的心头大患,今天来做一总结。
基础版(cin scanf两大流派)
普通的,给n(第一行题目就告诉接下来元素个数)的读法:
int n;
scanf流派就是: scanf("%d",&n) //一定要记得加&凹,要不然段错误
cin流派就: cin>>n;
然后再用一个for循环读取下面的元素
进阶版
进阶版就包括一些格式的处理了。
比如
- 分数的读入:L1-009 N个数求和 (20 分)
- 时间的读入:L1-018 大笨钟 (10 分) L1-043 阅览室 (20 分)
- 日期的读入:L1-042 日期格式化 (5 分)
这种带格式的读入cin往往不占便宜,一般使用scanf来读入固定格式的数据。
第一种用scanf("%d/%d",&变量,&变量)来读入分数。
第二种用scanf("%d:%d:%d",&hh,&mm,&ss)来读取时间
第三种用scanf("%d-%d-%d",&yy,&mm,&dd)来读取日期
复杂版
这个说来话长了,苦涩.jpg
说几个典型吧:
1.未知输入数据量读字符串L1-011 A-B (20 分) L1-023 输出GPLT (20 分)
如果碰到这种类型,需要读入一行的,建议使用getline(cin,s);(s为事先声明好了的string),因为gets用不了了。这样读入之后cout<<s;可以直接输出整串字符串。s.length()可以统计字符串长度。好处就是,可以拿这个字段当做for的上限,从0开始遍历整个串获取信息。(直接把这个string当做char数组使用)
- 已知读入规模,需要读取大量信息的 L1-054 福到了 (15 分)
这种让我头疼了好久,最后用getchar()读完的整个数据(getline应该也可以)。用两个for套着getchar()可以读完整个输入字符串。用法char c= getchar();需要注意的是,用getchar()和getline()之前,如果是另起一行开始读的,记得分别用一个getchar()、cin.ignore()吸收掉换行符’\n’ 这个题用getchar的好处就是直接读入一个非空格的字符直接用题目给的字符填入到字符串里。
输出的格式问题
简单来说,一般用scanf来输出。一开始会觉得特别蹩脚,写习惯了之后发现真的很好用!
比如:
printf("%05d",n);意思输出五位整数n,不足五位的话用0补齐
printf("%.2f",ans)这个也经常用到,意思是输出两位小数的ans。(不采用四舍五入)
这两种一般可以处理绝大部分的输出格式问题啦。
还有格式化问题,
一般字符转换为数字(以char a为例)就用a -= ‘0’;
一般大写转换为小写就用a = a - ‘A’ + ‘a’;
(如果不懂的话去补一补阿斯克码ASCII的相关知识)
今天就写到这里啦~以后想到什么再补充~
都看到这里啦~给个赞再走8