C++竞赛基础
学习内容
- 复习c++常用语法
- 做题找手感
C++语法
#include<iostream>
using namespace std; //声明命名空间std
int main(){
int a;
cin >>a; //cin 比 scanf慢很多,推荐scanf
cout <<a<<endl;
return 0;
}
引用替代指针
/*将a修改为b*/
#include<iostream>
using namespace std; //声明命名空间std
void change(int& a,int b);
int main(){
int a=0,b=1;
change(a,b);
return 0;
}
String类
#include<iostream>
#include<string>
using namespace std;
int main(){
string a("111");
cout <<a<<endl;
String b = "222";
cout <<b<<endl;
cout <<a+b<<endl;
cout <<a.length()<<endl;
cout <<a[0]<<endl;
return 0;
}
/*
输出结果
111
222
111222
3
1
*/
常用库函数——sort
/*
升序:sort(begin,end,less<data-type>());
降序:sort(begin,end,greater<data-type>()).
*/
#include<iostream>
#include<algorithm>
using namespace std;
bool check(int a,int b){
return a<b;
}
int main(){
int a[5] = {5,2,3,1,4};
sort(a,a+5,less<int>());
for(int i=0;i<4;i++)
cout <<a[i];
return 0;
}
#include<iostream>
#include<algorithm>
using namespace std;
bool check(int a,int b){
return a>b;
}
int main(){
int a[5] = {5,2,3,1,4};
sort(a,a+5,check);
for(int i=0;i<4;i++)
cout <<a[i];
return 0;
}
二分查找
int search(int *a,int n,int key){
int l=0,r=n-1,mid=0,ans=0;
while(l <= r){
mid = (r+1)/2;
if(a[mid] <= key){
l = mid+1;
ans=mid;
}else{
r = mid-1;
}
}
return a[ans] == key?ans:-1
}
二分直接调用库函数
/*
#include<algorithm>
binary_search 返回bool,判断是否存在
lower_bound 返回符合条件的第一个位置
upper_bound 返回最后一个位置
*/
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int a[] = {1,2,3,4,5,6,6,7,8,9,10};
int pos = lower_bound(a,a+11,6)-a; //返回的指针转化为首地址
cout <<pos<<endl;
}
cpp其他库函数
swap(a,b) 交换a,b
min(a,b) max(a,b)
- 动态数组 vector
- 队列 queue
- 栈 stack
- 双向队列 deque
- 优先队列
- 简单红黑树 set
- map
- 均有 empty() , size()
vector
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> v;
v.push_back(1); //动态数组放入元素
v.pop_back(); //弹出最后的元素
}
迭代器
#include<iostream>
#include<vector>
using namespace std;
int main(){
vector<int> v;
v.push_back(1); //动态数组放入元素
v.push_back(2);
v.push_back(3);
/*结果
5
*/
for(vector<int>::iterator it = v.begin();it != v.end();it++){
cout <<*it;
}
//迭代器for循环遍历
}
queue stack
#include<iostream>
#include<queue>
using namespace std;
int main(){
queue<int> q;
q.push(1);
q.push(2);
cout <<q.front();
q.pop();
cout <<q.back();
}
#include<iostream>
#include<stack>
using namespace std;
int main(){
stack<int> s;
s.push(1);
s.push(2);
cout <<s.top();
s.pop();
cout <<s.top();
}
优先队列 priority_queue
#include<iostream>
#include<queue>
using namespace std;
int main(){
priority_queue<int> q;
//相当于最大的元素在上面的堆
q.push(1);
q.push(5);
q.push(3);
cout <<q.top()<<endl;
q.pop();
cout <<q.top()<<endl;
return 0;
/*
运行结果
5
3
*/
}
set
自动去重 有序
#include<iostream>
#include<set>
using namespace std;
set<int> se;
int main(){
se.insert(1);
se.insert(2);
se.insert(1);
for(set<int>::iterator it = se.begin();it != se.end();it++){
cout <<*it<<endl;
}
return 0;
}
map
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main(){
map<string,int> mp; //map按照key的值排序 key->value键值对
map<string,int>::iterator it;
mp["2"] = 18;
mp["1"] = 0;
cout <<mp["1"]<<endl;
// 输出0
(*mp.find("1")).second = 5;
cout <<mp["1"]<<endl;
//输出5
for(it = mp.begin();it != mp.end();it++){
cout <<it->first<<" ";
cout <<it->second<<endl;
}
/*
输出
1 5
2 18
*/
}
计算第几天
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>
using namespace std;
bool check(int y){
return ((y%4) == 0 && (y%100)!=0) || (y%400) == 0;
}
int main(){
int a[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int y,m,d,sum = 0;
cin>>y>>m>>d;
if(check(y)){
a[2] = 29;
}
for(int i = 1;i<2m;i++){
sum+=a[i];
cout<<sum<<endl;
}
sum+=d;
cout<<sum;
}
素数
const int maxn = 100010;
int flag[maxn] = {0};
vector<int> prime;
for(int i = 2;i < maxn;i++){
if(flag == 0) prime.push_back(i);
for(int j = i + i;j < maxn;j += i){
flag[j] = 1;
}
}
求这样一个三位数,该三位数等于其中每位数字的的阶乘之和。
即; abc=a!+b!+c!
#include <iostream>
using namespace std;
int main()
{
for(int i=100;i++;i<=999){
long int a=0,b=0,c=0;
long int d=1,e=1,f=1;//注意清零,否则会超出内存
a=i%10;
b=i%100/10;
c=i/100;
for(int j=1;j<=a;j++)
d=d*j;
for(int q=1;q<=b;q++)
e=e*q;
for(int w=1;w<=c;w++)
f=f*w
if(i==(d+e+f))
{
cout<<i<<endl;
break;
}
}
return 0;
}
从键盘输入正整数n,求n!并输出
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>
using namespace std;
int fbs(int n){
if(n == 1){
return 1;
}
else{
return n*fbs(n-1);
}
}
int main(){
cout<<fbs(10);
}
统计输出整数100至100000之间所有数字之和为5的整数的总个数。
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>
using namespace std;
int main(){
int c = 0;
for(int i = 100;i<=100000;i++){
int v=0;
int n = i,t=0,sum=0;
while(n){
v = n%10;
sum+=v;
n = n/10;
}
if(sum == 5){
c++;
}
}
cout<<c;
}
斐波那契: F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
int f(int n){
if(n == 0){
return 0;
}
if(n == 1){
return 1;
}
return f(n-1)+f(n-2);
}
int main(){
cout<<f(3);
}
最大公约数
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int a,b;
cin>>a>>b;
cout<<__gcd(a,b)<<endl;
}
#include<iostream>
#include<algorithm>
using namespace std;
int gcd(int a,int b) {
if(a%b==0)
return b;
else
return (gcd(b,a%b));
}
a,b的最小公倍数,就是ab除以a,b的最大公约数。即ab/gcd(a,b)
string型反转:
头问件:#include
string a;
reverse(a.begin(),a.end());
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
string s;
cin>>s;
reverse(s.begin(),s.end());
cout<<s;
}
数字逆置
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int main(){
int n;
cin>>n;
int t = -1,s = n;
while(s){
t++;
s/=10;
}
while(n){
int x = n%10;
s+=x*pow(10,t--);
n/=10;
}
cout<<s;
}
二分
int a[1010]={0,1,7,7,7,13,100};//必须有序
cout<<”a数组从a[1]到a[n]这n个数中有7吗?”<<binary_search(a+1,a+n+1,7)<<endl;
cout<<”a数组从a[1]到a[n]这n个数中第一个大于等于10的数的下标?”<< lower_bound(a+1,a+n+1,10)-a<<endl;
cout<<”a数组从a[1]到a[n]这n个数中第一个大于10的数的下标?”<< upper_bound(a+1,a+n+1,10)-a<<endl;
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int main(){
int a[8] = {1,2,6,8,4,6,66,99};
int i = 0;
if(binary_search(a+1,a+9,66)){
i = lower_bound(a+1,a+10,66)-a;
cout<<i<<endl;
cout<<a[i];
}
}
链表排序
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
struct node{
int data;
struct node *next;
};
int n;
struct node *create(){
struct node *head,*pre,*now; //头 尾 当前
for(int i = 1;i<=n;i++){
now = (struct node*)malloc(sizeof(node));
int num;
cin>>num;
now->data = num;
if(i == 1){
head = now;
pre = now;
}
else{
pre->next = now;
pre = now;
}
}
return head;
}
void sorts(struct node *head){
struct node *now,*pre,*p;
now = head;
pre = now;
now = now->next;
for(int i = 1;i<n;i++){
for(int j = 1;j<n;j++){
if(pre->data>now->data){
int temp = pre->data;
pre->data = now->data;
now->data = temp;
}
pre = now;
now = pre->next;
}
now = head;
pre = now;
now = now->next;
}
p = head;
for(int i = 1;i<=n;i++){
cout<<p->data<<" ";
p = p->next;
}
}
int main(){
cin>>n;
struct node *head;
head = create();
sorts(head);
}
///数组冒泡
#include <iostream>
#include <vector>
using namespace std;
//从小到大排序
void bubbleSort_MinToMax(vector<int> &numberList)
{
int N = numberList.size();
for (int i = 1; i < N; i++)
{
for (int j = 0; j < N - i; j++)
{
if (numberList[j] > numberList[j + 1])
{
//交换
int buffer = numberList[j];
numberList[j] = numberList[j + 1];
numberList[j + 1] = buffer;
}
}
}
}
先序遍历
struct tree{
int data;
struct tree* l;
struct tree* r;
};
void preorder(tree* root){
if(root == null){
return;
}
cout<<root->data<<" ";
preorder(root->l);
preorder(root->r)
}