今天我们来总结一下struct和typedef struct在C语言和C++里的不同
#include
using namespace std;
int main(){
int a[4]={1,2,3,4};
sort(a,a+4);
do{
for(int i=0;i<4;i++){
cout<<a[i]<<" ";
}
cout<<endl;
}while(next_permutation(a,a+4));
return 0;
}
#include
using namespace std;
int main(){
string str;
cin>>str;
sort(str.begin(),str.end());
do{
cout<<str<<endl;
}while(next_permutation(str.begin(),str.end()));
return 0;
}
#include
在这个头文件里面
判断是否为十进制数字isdigit
如果 c 是一个数字,则该函数返回非零值,否则返回 0。
判断是否为字母isalpha
如果 c 是一个字母,则该函数返回非零值,否则返回 0。
判断是否为数字或者字母isalnum
如果 c 是一个数字或一个字母,则该函数返回非零值,否则返回 0
const int * a;
const修饰的是整型数 int,而不是指针,即a是一个指向常整型数的指针。近一步的理解为:整型数 a是不可以被重新赋值的,而指针却是可以修改的,可以重新指向另外一个内存地址;
int * const a;
const修饰的是指针a,而不是整型数a,*a为变量而不是一个常量。即a是指向一个可以修改的整型数的常指针。进一步的理解为:指针指向的整型数是可以被修改的,但是指针不可以被修改。
int const * a const;
a是指向一个常整型数的常指针,即指针不可修改,指针指向的整型数也是不可以被修改的。
判断奇数偶数
一个数的二进制里面有几个1
a^a=0;
a^b=不为0;
其他的
1&1=1;
1&2=0;
#include
using namespace std;
int main(){
int n,i,a[20],m=-1;
scanf("%d",&n);
while(n){
i=n%2;
a[++m]=i;
n=n/2;
}
for(int j=m;j>=0;j--)
printf("%d",a[j]);
printf("\n");
int ans;
for(int i=0;i<=m;i++){
if(1^a[i]==0){
ans++;
}
}
printf("%d ",ans);
// cout << bitset<32>(n) << endl;
}
投机取巧的学了一丢丢excel里面计算日期的小tips
#include
int main(){
int ans=0;
for(int i=1;i<=2020;i++){
int m=i;
while(m){
if(m%10==2){
ans++;
}
m/=10;
}
}
printf("%d",ans);
return 0;
}
#include
#include
#include
#include
#include
using namespace std;
int main(){
int ans=0;
for(int i=1;i<=2020;i++){
for(int j=1;j<=2020;j++){
if(__gcd(i,j)==1){
ans++;
}
}
}
printf("%d",ans);
return 0;
}
#include
int a[100][100];
int cnt=1;
int main(){
int i;
int x,y;
for(i = 1 ; i <= 40; i++){
if(i % 2==1 ){
for(x = i, y = 1; x >= 1 && y <= i; x--, y++)
a[x][y] = cnt++;
}
else{
for(int x = 1, y = i; x <= i && y >= 1; x++, y--)
a[x][y] = cnt++;
}
}
printf("%d\n", a[20][20]);
return 0;
}
#include
int main(){
int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int w=6;
int sum=0;
for(int y=2000;y<=2020;y++){
if((y%400==0)||(y%4==0&&y%100!=0)){
a[2]=29;
}else{
a[2]=28;
}
for(int m=1;m<=12;m++){
for(int d=1;d<=a[m];d++){
if(d==1||w==1){
sum+=2;
}else{
sum+=1;
}
w=(w+1)%7;
if(y==2020&&m==10&&d==1){
printf("%d",sum);
return 0;
}
}
}
}
}
#include
#include
#include
using namespace std;
int main(){
int n;
scanf("%d",&n);
int a[1005];
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
int jige=0;
int youxiu=0;
for(int i=1;i<=n;i++){
if(a[i]>=60){
jige++;
}
if(a[i]>=85){
youxiu++;
}
}
printf("%.0lf%%\n%.0lf%%",jige*100/n,youxiu*100.0/n);
return 0;
}
#include
#include
using namespace std;
bool last[26];
string str;
long long judge(int x,int y){
memset(last,0,sizeof(last));
long long ans=0;
for(int i=x;i<=y;i++){
last[str[i]-'a']=1;
}
//ababc
for(int i=0;i<=26;i++){
ans+=last[i];
}
return ans;
}
int main(){
cin>>str;
int n=str.size();
long long ans=0;
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
ans+=judge(i,j);
}
}
cout<<ans<<endl;
}
#include
#include
using namespace std;
int main(){
stack<char>s;
int a;
cin>>a;
while(a){
int x=a%26;
if(x==0){
x=26;
}
a=(a-x)/26;
s.push('A'+x-1);
}
while(!s.empty()){
cout<<s.top();
s.pop();
}
return 0;
}
#include
using namespace std;
long long a[20190325];
int main(){
a[1]=1;
a[2]=1;
a[3]=1;
for(int i=4;i<=20190324;i++){
a[i]=(a[i-1]+a[i-2]+a[i-3])%10000;
}
cout<<a[20190324]<<endl;
return 0;
}
#include
using namespace std;
bool check(int x, int y, int z) {
int res = 0;
while (x) {
res = x % 10;
if (res == 2 || res == 4) return false;
x /= 10;
}
while (y) {
res = y % 10;
if (res == 2 || res == 4) return false;
y /= 10;
}
while (z) {
res = z % 10;
if (res == 2 || res == 4) return false;
z /= 10;
}
return true;
}
int main() {
int ans = 0;
for (int a = 1; a < 2019; a++) {
for (int b = 1; b < 2019; b++) {
if (b == a){
continue;
}
for (int c = 1; c < 2019; c++) {
if (b == c || a == c){
continue;
}
if (a + b + c == 2019 && check(a, b, c)){
ans++;
}
}
}
}
cout << ans / 6 << endl;
return 0;
}
#include
using namespace std;
bool check(int n){
while(n){
int temp=n%10;
if(temp==0||temp==1||temp==2||temp==9){
return true;
}
n/=10;
}
return false;
}
int main(){
int ans;
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
if(check(i)){
ans+=i;
}
}
cout<<ans;
return 0;
}
#include
using namespace std;
char mp[30][50];
bool vis[30][50];
int dir[4][2] = {{1,0},{0,-1},{0,1},{-1,0}};
char dirc[4] = {'D','L','R','U'};
int n,m;
struct node{
int x; //横坐标
int y; //纵坐标
int step; //步数
string str; //路径
node(int xx, int yy, int ss, string s) { //构造函数
x = xx;
y = yy;
step = ss;
str = s;
}
};
queue<node> q; //创建队列
bool check(int x, int y) { //判断是否越界以及是否是墙以及是否访问过了
if (x < 0 || x >= n || y < 0 || y >= m || vis[x][y] || mp[x][y] == '1') {
return false;
}
return true;
}
void bfs(int x, int y) {
q.push(node(x, y, 0, ""));
vis[x][y] = true;
while (!q.empty()) {
node now = q.front();
if (now.x == n - 1 && now.y == m - 1) { //到达终点了
cout << now.str << endl;
cout << now.step << endl;
break;
}
q.pop();
for (int i = 0; i < 4; i++) {
int nx = now.x + dir[i][0];
int ny = now.y + dir[i][1];
if (check(nx, ny)) {
q.push(node(nx, ny, now.step + 1, now.str + dirc[i]));
vis[nx][ny] = true;
}
}
}
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) {
scanf("%s", mp[i]);
}
bfs(0, 0);
return 0;
}
#include
using namespace std;
int main(){
int n,cha,ans;
scanf("%d",&n);
int a[100005];
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
sort(a+1,a+n+1);
if(a[1]==a[n]){
cout<<n<<endl;
}else{
cha=a[2]-a[1];
ans=(a[n]-a[1])/cha+1;
cout<<ans<<endl;
}
return 0;
}
#include
#include
using namespace std;
int main(){
for(int i=1;i*5<=200;i++){
for(int j=1;j<=200;j++){
for(int k=1;k*2<=200;k++){
if((k*2+j+i*5==200)&&(j*10==k)){
cout<<i<<" "<<k<<" "<<j<<endl;
}
}
}
}
return 0;
}
#include
#include
int main(){
char a[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int n,m,i,j,k;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++){
for(j=0;j<m;j++){
k=abs(i-j);
printf("%c",a[k]);
}
printf("\n");
}
return 0;
}
#include
在这个头文件里面
判断是否为十进制数字isdigit
如果 c 是一个数字,则该函数返回非零值,否则返回 0。
判断是否为字母isalpha
如果 c 是一个字母,则该函数返回非零值,否则返回 0。
判断是否为数字或者字母isalnum
如果 c 是一个数字或一个字母,则该函数返回非零值,否则返回 0
const int * a;
const修饰的是整型数 int,而不是指针,即a是一个指向常整型数的指针。近一步的理解为:整型数 a是不可以被重新赋值的,而指针却是可以修改的,可以重新指向另外一个内存地址;
int * const a;
const修饰的是指针a,而不是整型数a,*a为变量而不是一个常量。即a是指向一个可以修改的整型数的常指针。进一步的理解为:指针指向的整型数是可以被修改的,但是指针不可以被修改。
int const * a const;
a是指向一个常整型数的常指针,即指针不可修改,指针指向的整型数也是不可以被修改的。
int型变量的一维数组最多是3千万,long long型1千5百万,char型1亿左右。
1、基本输入输出语法:
(1)如cin速度比scanf慢 两者遇到空格回车会停止读入
(2)若想读整行需要cin.getline()或gets函数
(3)读到文件尾用scanf()!=EOF等等
(4)占位符‘%’相关格式,如对齐方式,补0等。
#include
#include
//个人觉得可以用#include
using namespace std;
void main(){
int x=1000;
double y=1.23456789;
cout<<"默认x值:"<<x<<endl;
cout<<"十进制:"<<dec<<x<<endl;//decocthex会一直作用。
cout<<"八进制:"<<oct<<x<<endl;
cout<<"十六进制:"<<hex<<x<<endl;
cout<<"十六进制(大写字母):"<<hex<<uppercase<<x<<endl;
cout<<"默认y值(左对齐且有效数字位数为6):"<<y<<endl;
cout<<"宽度为10并右对齐:"<<setw(10)<<right<<y<<endl;
cout<<"宽度为4:"<<setw(4)<<y<<endl;
cout<<"用*号填充空位(10位宽度):"<<setfill('*')<<setw(10)<<y<<endl;//setw(inti)只对紧随的数据显示有影响。控制多个数据要多个setw()
cout<<"设精度为8输出y(不包括小数点):"<<setprecision(8)<<y<<endl;//如果小数位数不足8位,则输出完整的小数
cout<<"设精度为8输出y(不包括小数点):"<<fixed<<setprecision(8)<<y<<endl;//如果小数位数不足8位,则输出的小数结尾用0补齐8位
cout<<"显示正负号:"<<showpos<<y<<endl;
cout<<"用科学计数法表示y:"<<scientific<<y<<endl;
cout<<"用科学计数法表示y(控制E前数据的小数点后位数):"<<scientific<<setprecision(3)<<y<<endl;}
2、C/C++库函数以及stl模板
(1)algorithm: sort next_permutation ——gcd() lower_bound/upper_bound
(2)queue(priority_queue) stack vector set map基本操作等
3、数据结构
(1)结构体:注意结构体用sort排序,可自定义cmp函数
(2)字符串:string类的使用 查找首次出现的位置 统计总共出现的次数
(3)栈、队列:前缀、后缀表达式计算等。
(4)图:两种表示方法,邻接表和邻接矩阵,当n较大时只能采用邻接表。
(5)树:树是一种特殊的图。如按层输出节点等
(6)线段树:基本的单点修改、区间修改、区间查询等。
4、算法
(1)暴力:蓝桥杯又称暴力杯,n<=1e3(1000),O(n^ 2)的代码大概率能解,如果1e4<=n<=1e6,则要考虑O(n*logn)的算法,不过蓝桥按测试点得分,实在不会,可用O(n^2)骗分,骗到了就是赚到了。
(2)思维:不涉及算法,不涉及复杂数据结构,往往几行代码就可以解决,考验思维能力,多训练此类题目即可。
(3)模拟:模拟指根据题目描述,按部就班的写代码就可以AC,通常思路容易看出但是代码量较大,考验细节与心态。
①大数加减法
②进制转换
(4)数学问题:
①质数相关:埃式筛、欧拉筛、唯一分解定理等。
②求最大公因数:要自己会写gcd函数(欧几里得算法)
(5)贪心
(6)动态规划:
①最长公共子序列
③背包问题(01背包、多重背包、完全背包等)
(7)搜索:搜索基本是必考的点,包括DFS/BFS,可分别用栈和队列模拟。记忆化搜索也是常考的点,用于避免重复搜索。
(8)图论:
①最短路:最基本要掌握两种求法,floyd算法和dijkstra算法。前者O(n^3),适用于n不大于500的情况。后者dijkstra用的较多,数据结构实现有两种,邻接矩阵与邻接表,建议用邻接表(具体实现啊哈算法上有)。
②最小生成树:kruscal算法和prim算法
③拓扑排序
(9)字符串:回文、kmp算法(字符串匹配算法)
(10)其他:并查集、二分/三分算法等