1.顺序结构
if(~scanf("%d",&a));//判断是否是非法输入(EOF)
2.判断结构
使用printf时最好加上头文件#include
- float 默认保留6位小数
- double 默认保留6位小数
- %8.3f 表示最小宽度为8,保留3位小数,当宽度不足时在前面补空格
- %-8.3f 宽度不足时在后面补空格
- %08.3f 宽度不足时在前面补0
3.循环结构
输入一个n,打印n阶菱形。n是奇数
n=9时的结果:
int n;
cin>>n;
int cx=n/2,cy=n/2;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(abs(i-cx)+abs(j-cy)<=n/2)
cout<<"*";
else cout<<' ';
}
cout<<endl;
}
4.数组
int c[5] = {0,1,2};//等价于c[]={0,1,2,0,0}
- 输入一个n,再输入n个整数。将这个数组顺时针旋转k(k <= n)次,最后将结果输出。
int a[100];
reverse(a,a+k);
reverse(a+k,a+n);
reverse(a,a+n);
- 计算2的N次方。N <= 10000
int a[10000],size=1,n;
a[0]=1;
cin>>n;
while(n--)
{
int t=0;
for(int i=0;i<size;i++)
{
t+=a[i]*2;
a[i]=t%10;
t/=10;
}
if(t)a[size++]=t;
}
for(int size-1;i>=0;i--)cout<<a[i]<<' ';
cout<<endl;
- 输入一个n行m列的矩阵,从左上角开始将其按回字形的顺序顺时针打印出来。(蛇形矩阵)
int res[100][100];
int n,m;
cin>>n>>m;
int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
for(int x=0,y=0,d=0,k=1;k<=n*m;k++)
{
res[x][y]=k;
int a=x+dx[d],b=y+dy[d];
if(a<0 || b<0 || a>=n || b>=m || res[a][b])
{
d=(d+1)%4;
a=x+dx[d],b=y+dy[d];
}
x=a,y=b;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)cout<<res[i][j]<<' ';
cout<<endl;
}
5.字符串
- 每个常用字符都对应一个-128~127的数字
A~Z: 65~90
a~z: 97~122
0~9: 48~57
- 字符串就是字符数组加上结束符’\0’,因此字符数组的长度至少要比字符串长度多1
char a[6] = "Daniel"; //错误
- 输入输出
char str[100];
cin>>str;
cout<<str;
printf("%s\n",str);
char str[100];
gets(str);
cout<<str;
- string.h
strlen(str); 长度
strcmp(a,b);a<b 返回-1
strcpy(a,b);b复制给a
- string
string s;
cin>>s;
printf("%s",s.c_str()); //这样写是对的,其他不对
getline(cin,s); //读一行
string s="abc";
cout<<s.empty();
string的比较
支持> < !=等所有比较操作,按字典序比较
string s1(10,'c');//cccccccccc
必须保证至少有一个是string类型
string s1="cc";
string a=s1+"hello";//True
string a="hello"+"world";//False 两个都不是string类型
for(char &c : s) c='a';
6.函数
7.类,结构体
- private:私有成员变量,类的外部不能访问
- public:公有成员变量,类的外部可以访问
class Person
{
private:
int age,height;
public:
string name;
void say()
{
cout<<"I'm "<<name<<endl;
}
}person_a,person_b,persons[100];
- 结构体和类的作用是一样的,不同点在于类默认是private,结构体默认是public
struct Person
{
private:
int age,height;
double money;
public:
string name;
void say()
{
cout<<"I'm "<<name<<endl;
}
int set_age(int a)
{
age = a;
}
int get_age()
{
return age;
}
void add_money(double x)
{
money+=x;
}
}person_a,person_b,persons[100];
8.指针,引用
- 指针指向存放变量的地址,可以通过指针修改变量的值
int a=10;
int *p=&a;
*p+=5;
cout<<*p<<endl;
数组名是一种特殊的指针
int a[5]={1,2,3,4,5};
for(int i=0;i<5;i++)cout<<*(a+i)<<endl;
引用和指针类似,相当于给变量起了个别名
int a=10;
int &p=a;
p+=5;
cout<<p<<endl;
9.链表
struct Node
{
int val;
Node *next;
}*head;
int main()
{
//反转链表
for(int i=1;i<=5;i++)
{
Node *p=new Node();
p->val=i;
p->next=head;
head=p;
}
for(Node *p=head;p;p=p->next)cout<<p->val<<' ';
cout<<endl;
}
- 注意:链表中的头结点指的是链表第一个结点的地址,而不是结点本身。
10.STL
vector
vector<int> a;//一维数组
vector<int> b[N];//二维数组
vector<int> a({1,2,3});
a.empty()/a.size();//所有STL容器都支持这两个方法
a.clear();
a.front();
a.back();//最后一个元素
pop_back();//删除末尾元素
要求数组有序
int *p=lower_bound(a,a+a.size(),x); //查找大于等于x的元素地址
int *p=upper_boubd(a,a+a.size(),x); //查找小于x的元素地址
for(auto i=a.begin();i<a.end();i++)
for(int x:a)
*a.begin()==a[0]
a.end()-a.begin()==a.size()
queue
queue<int> q;
q.push(x);
int x=q.pop();//删除第一个元素
a.front
a.back
优先队列
priority_queue<int> a;//大根堆
priority_queue<int,vector<int>,greater<int>> b;//小跟堆
struct Rec
{
int a,b;
//大根堆
bool operator< (const Rec& t)const
{
return a<t.a;
}
//小根堆
bool operator> (const Rec& t)const
{
return a>t.a;
}
}
priority_queue<Rec> a;//大根堆
priority_queue<Rec,vector<Rec>,greater<Rec>> b;//小根堆
a.push
a.top
a.pop
- 优先队列插入时无序,输出时有序
- 大根堆<,小根堆>
stack
stack<int> s;
s.push
s.top
s.pop
deque(双端队列)
deque<int> q;
q.front
q.back
push_back
push_front
pop_back
pop_front
set
set<int> s;//集合
multiset<int> ms;//多重集合,允许元素重复
s.clear
s.insert
s.find(x);//返回迭代器,可用if(s.find(x)==s.end())判断是否存在x
s.lower_bound(x);//大于等于
s.upper_bound(x);//小于
s.erase(x);//删除x并返回迭代器
s.count(x);//x个数
unordered_set
unordered_set<int> s;//哈希表
unordered_multiset<int> s;
- find、erase、lower_bound,upper_bound都是O(logn)复杂度
- count是O(k+logn)复杂度
bitset
- bitset元素支持位运算符&、|、~等等
- 求x第k位二进制数:x>>k&1
- 求x最后一个1:lowbit(x) = x&(-x);
pair
pair<int,int> a={5,6};
pair<int,int> b=make_pair(5,6);
map
map<string,int> m;
a['c']=4;
m.insert
m.find
unordered_map哈希映射,效率更高
algorithm
vector<int> a;
去重
unique(q,a+a.size());//返回去重后最后一个元素的地址
int m=unique(a,a+a.size())-a;//去重后数组的长度
a.erase(unique(a.begin(),a.end()),a.end());//删除重复元素
打乱
random_shuffle(a.begin(),a.end());
常结和ctime的srand(time(0))使用
排序
sort(a.begin(),a.end(),greater<int>());//降序
- unique并没有真的删除重复元素,只是将重复元素放到非重复元素部分的右边
11.位运算
- lower_bound/upper_bound 二分
int l = lower_bound(a+1,a+1+n,x)-a;//下标1~n中大于等于x的最小整数的下标
int y = *upper_bound(a.begin(),a.end(),x);//查找小于等于x的最大整数
12.补充
-
8Mb:8兆带宽,就是1MB速度下载
-
-5%2=-1,前面是正结果为正,前面是负结果为负
-
char->int 小的向大的转换
-
%只用与整数
-
scanf("%c %c",&a,&b);//会把空格读入
cin>>a>>b;//忽略中间空格
OJ系统输出格式问题:
- 忽略每一行末尾的空格
- 忽略输出结果最后的换行符
max数学表达式可以通过几何理解:
有些语言中(4/3)无法得到1.33333…,建议用(4.0/3)
梯形面积:(a+b)*c/2
判断闰年
if(y%400==0 || y%100 && y%4==0)
- 奇数可以是正数,也可以是负数
取得是第二个
EOF就是-1