欢迎光临
我们一直在努力

C++基础知识

一、整数与字符

1.1 整数的定义

int a;
short b;
long c;
long long c;
//除法/正常整除,有浮点数是正常除运算,%是取余

image-20250603174622314

整数大小可以用sizeof()进行探测,这不是函数,在编译阶段就被求值了。

1.2 字符类型(本质也是整数)

char a='A';//字符的字面量表达用:单引号,不能包含汉字和多个字母
char b=65;
int c=a;
char x=',';

1.3 浮点类型

二、类型转换

2.1 自动转换和强制转换

2.2 四舍五入

数学原理:(a + b – 1) / b等价于 ceil(a / b)(向上取整)。

三、基础知识

3.1 布尔逻辑

3.2 交换变量

int a[3];
for(int i=0;i<3;i++){
cin>>a[i];
}
int n;
for(int k=0;k<2;k++){
for(int j=0;j<2-k;j++){
if(a[j]>a[j+1]){
int m=a[j];
a[j]=a[j+1];
a[j+1]=m;
}
}
}
for(int i=0;i<3;i++){
cout<<a[i]<<" ";
}
return 0;

3.3 int存储最大数字

#include <iostream>
#include <climits> //INT_MAX是int的最大值
using namespace std;
int main() {
long long max_value=INT_MAX;
long long result=INT_MAX/100000000;
   cout<<result;
   return 0;
}

3.4 输出等腰三角形(循环)

#include <iostream>
using namespace std;
int main(){
string a;
cin>>a;
for(int i=1;i<=3;i++){
for(int j=1;j<=3-i;j++){
cout<<" ";
}
for(int k=1;k<=2*i-1;k++){
cout<<a;
}
cout<<endl;
}
return 0;
}

3.5关于时间(洛谷)

#include <iostream>
#include <iomanip>
using namespace std;
int main(){
   int s,v,time;
   cin>>s>>v;
   if(s%v==0){
  time=s/v;
}
else{
time=s/v+1;
}
int total_time=time+10;
int total_minutes=8*60-total_time;
   // 处理跨天情况(如果total_minutes为负数)
   if (total_minutes < 0) {
       total_minutes += 24 * 60;  // 加上一天的分钟数(1440分钟)
  }
int hours=total_minutes/60;
int minutes=total_minutes%60;
cout<<setw(2)<<setfill('0')<<hours<<":"   //设置宽度为2,用0填充空白的宽度位置
<<setw(2)<<setfill('0')<<minutes;
   return 0;
}

3.6 旗帜翻转问题

#include<iostream>
using namespace std;
int h[1000000],l[1000000];
int main()
{
int n,m,k;
cin>>n>>m>>k;
while(k–){
char c;
int num;
cin>>c>>num;
if(c=='R'){
h[num]++;
}
if(c=='C'){
l[num]++;
}
}
long long f1=0,f2=0,f3=0,f4=0;
for(int i=1;i<=n;i++){
if(h[i]%2==1) f1++;//奇数行
if(h[i]%2==0) f2++; //偶数行
}
for(int i=1;i<=m;i++){
if(l[i]%2==1) f3++;//奇数列
if(l[i]%2==0) f4++; //偶数列
}
cout<<f1*f4+f2*f3;
return 0;
}

#include <iostream>
using namespace std;
int main(){
  int n,m,k;
  cin>>n>>m>>k;
  //记录每行每列被翻转的次数
  // 使用动态数组避免大小限制
   int* row = new int[n + 1]();  
   int* col = new int[m + 1]();  
  for(int i=0;i<k;i++){
  char op;
int num;//对哪行/列操作
cin>>op>>num;  
if(op=='R'&&num<=n){
row[num]++;
}
if(op=='C'&&num<=m){
col[num]++;
}
}
long long int rows=0,cols=0;
for(int i=1;i<=n;i++){
if(row[i]%2==1){
rows++;
}
}
for(int j=1;j<=m;j++){
if(col[j]%2==1){
cols++;
}
}
long long int green=rows*m+cols*n-2*rows*cols;
cout<<green;
// 释放内存
   delete[] row;
   delete[] col;
   return 0;
}

#include<iostream>
using namespace std;
int h[1000005],l[1000005];
int main()
{
long long int n,m,k,num,sh=0,sl=0,s;
char c;
cin>>n>>m>>k;
for(int i=1;i<=k;i++)
{
cin>>c>>num;
if(c=='R')
{
h[num]=(h[num]+1)%2;//奇数+偶数=奇数   奇偶型来判断颜色。
if(h[num]==1)
{
sh++;
}
else
{
sh–;
}
}
else
{
l[num]=(l[num]+1)%2;
if(l[num]==1)
{
sl++;
}
else
{
sl–;
}
}
}
//行操作为偶数次的话,列操作一定是奇数,所以行加列结果等于奇数是一定有一个是奇数(绿色)
s=sh*(m-sl)+sl*(n-sh);
cout<<s;
return 0;
}

3.7 二级 菱形(洛谷)

#include <iostream>
using namespace std;
int main() {
   int n,x;
cin>>n;
x=(n+1)/2;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==1&&j==x||i==n&&j==x||j==1&&i==x||j==n&&i==x){
cout<<"#";
}
else if(i+j==x+1||j-i==x-1||i-j==x-1||i+j==x+n){
cout<<"#";
}
else{
cout<<".";
}
}
cout<<endl;
}
   return 0;
}

#include <iostream>
using namespace std;
int main() {
   int n,x,y;
cin>>n;
x=(n+1)/2;
y=(n+1)/2;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(j==x||j==y) cout<<"#";
else cout<<".";
}
if(i<(n+1)/2){
x–;
y++;
}
else{
x++;
y–;
}
cout<<endl;
}
   return 0;
}

万能头:#include <bits/stdc++.h>

几位数的格式化:setw(2) << setfill('0');头文件:<iomanip>

3.8 填坑问题(提高组)

  • 题目背景

    NOIP2018 提高组 D1T1

    题目描述

    春春是一名道路工程师,负责铺设一条长度为 n 的道路。

    铺设道路的主要工作是填平下陷的地表。整段道路可以看作是 n 块首尾相连的区域,一开始,第 i 块区域下陷的深度为 d**i 。

    春春每天可以选择一段连续区间 [L,R] ,填充这段区间中的每块区域,让其下陷深度减少 1。在选择区间时,需要保证,区间内的每块区域在填充前下陷深度均不为 0 。

    春春希望你能帮他设计一种方案,可以在最短的时间内将整段道路的下陷深度都变为 0 。

    输入格式

    输入文件包含两行,第一行包含一个整数 n,表示道路的长度。 第二行包含 n 个整数,相邻两数间用一个空格隔开,第 i 个整数为 d**i 。

    输出格式

    输出文件仅包含一个整数,即最少需要多少天才能完成任务。

    输入输出样例

    输入 

    6  
    4 3 2 5 3 5

    输出 

    9

    说明/提示

    【样例解释】

    一种可行的最佳方案是,依次选择: [1,6]、[1,6]、[1,2]、[1,1]、[4,6]、[4,4]、[4,4]、[6,6]、[6,6]。

    【数据规模与约定】

    对于 30% 的数据,1≤n≤10 ; 对于 70% 的数据,1≤n≤1000 ; 对于 100% 的数据,1≤n≤100000,0≤d**i​≤10000 。

  • //70分模拟
    #include <iostream>
    using namespace std;
    int d[100005];
    int main(){  
    int n,i,start,end,cnt=0;
    cin>>n;
    for(i=1;i<=n;i++){
    cin>>d[i];
    }
    while(1){
    start=-1;
    for(i=1;i<=n;i++){
    if(d[i]!=0){
    start=i;
    break;
    }
    }
    if(start==-1) break;
    for(i=start;i<=n;i++){
    if(d[i]==0){
    break;
    }
    end=i;
    }
    for(i=start;i<=end;i++){
    d[i]–;
    }
    cnt++;
    }
    cout<<cnt;
    return 0;  
    }  

    //100分代码
    #include <iostream>
    using namespace std;
    int d[100005],dp[100005];
    int main(){  
    int n,i;
    cin>>n;
    dp[1]=d[1];
    for(int i=2;i<=n;i++){
    cin>>d[i];
    //dp[i]=dp[i-1]+max(0,d[i]-d[i-1]); //动态规划
    if(d[i]<d[i-1]){
    dp[i]=dp[i-1];
    }
    else{
    dp[i]=dp[i-1]+d[i]-d[i-1];
    }
    }
    cout<<dp[n];
    return 0;  
    }  

    //100分贪心算法(算法思想:全局最优/局部最优)
    #include <iostream>
    using namespace std;
    int d[100005];
    int main(){  
    int n,i,cnt=0;
    cin>>n;
    for(int i=1;i<=n;i++){
    cin>>d[i];
    }
    for(int i=1;i<=n;i++){
    if(d[i]-d[i-1]>=0){
    cnt+=d[i]-d[i-1];
    }
    }
    cout<<cnt;
    return 0;  
    }  
    //贪心算法–空间优化

    #include <iostream>
    using namespace std;
    int main(){  
    int n,i,cnt=0,prev=0,cur=0;
    cin>>n;
    for(int i=1;i<=n;i++){
    cin>>cur;
    if(cur-prev>=0){
    cnt+=cur-prev;
    }
    prev=cur;
    }
    cout<<cnt;
    return 0;  
    }  

四、PTA算法

1.连续子序列最大和

给定 n 个整数组成的序列 { a1,a2,⋯,a**n },“连续子序列”被定义为 { a**i,a**i+1,⋯,a**j },其中 1≤i≤j≤n。“连续子序列最大和”则被定义为所有连续子序列元素的和中最大者。例如给定序列 { -2, 11, -4, 13, -5, -2 },其连续子序列 { 11, -4, 13 } 有最大的和 20。请编写程序,计算给定整数序列的连续子序列最大和。

本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下:

  • 数据 0~6:测试基本正确性;

  • 数据 7:103 个随机整数;

  • 数据 8:104 个随机整数;

  • 数据 9:105 个随机整数。

输入格式:

输入第一行给出正整数 n (≤105);第二行给出 n 个整数,绝对值均不超过 100,其间以空格分隔。

输出格式:

在第一行中输出连续子序列最大和,第二行输出该子序列首尾的数组下标(从 0 开始),以 1 个空格分隔。若解不唯一,则输出最小的数组下标(如样例所示)。 注意:如果序列中所有整数皆为零或负数,则取空子列的结果是最大的,为 0;此时空子序列数组首尾的下标均为 -1。

输入样例:

10
-10 2 2 3 4 -5 -23 4 7 -21

输出样例:

11
1 4

#include <iostream>
#include <cmath>
using namespace std;
int main() {
int n,a[100010];
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
long long cur=0,best=0; // cur: 当前子序列和,best: 最大子序列和
int t=0,l=-1,r=-1;// t: 当前子序列起始位置,l/r: 最大子序列的左右边界
// 主循环:寻找最大子序列
for(int i=0;i<n;i++){
if(cur<0){ //重新开始一段
cur=a[i];// 当前和重置为a[i]
t=i; // 记录新的起始位置
}
else{ // 否则继续扩展当前子序列
cur+=a[i];
}
if(cur>best){ //刷新全局最大
best=cur;
l=t;
r=i;
}
}
if(best<0){//最大和为负数输出无效边界和0
cout<<0<<endl;
cout<<"-1 -1";
}
else{
cout<<best<<endl;
cout<<l<<" "<<r;
}
return 0;
}

赞(0)
未经允许不得转载:171主机测评 » C++基础知识
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址