1隐藏的排序

题目描述

每个箱子都有长宽高,我们需要判断一个箱子能否放入另一个箱子中。

例如有箱子A的尺寸是 3 x 4 x 5,箱子B的尺寸 是 5 x 6 x 4,经过比较判断,可以知道箱子A能够放入箱子B中,我们就说箱子A匹配箱子B。

注意,当两个箱子尺寸相等,我们也认为它们匹配。

输入给你的是 “长、宽、高” 三个数,但没规定哪个是哪个,箱子可以旋转,所以不能直接按输入顺序比,必须先排序。

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		long a[3];
		long b[3];
		cin>>a[0]>>a[1]>>a[2];
		cin>>b[0]>>b[1]>>b[2];
		sort(a,a+3);
		sort(b,b+3);
		if((a[0]<=b[0]&&a[1]<=b[1]&&a[2]<=b[2])||(a[0]>=b[0]&&a[1]>=b[1]&&a[2]>=b[2]))
		{
			cout<<"yes"<<endl;
		}
		else
		{
			cout<<"no"<<endl;
		}
	}
	return 0;
}

2字符串

题目描述

有一种古典加密方法就是按照字母表顺序,把每个字母循环右移k位,从而转换为加密的另一个字母。

例如偏移2位,即A对应C,B对应D,……X对应Z,Y对应A,Z对应B;同样a对于c,b对应d,……x对应z,y对应a,z对应b。

如果输入的不是字母则忽略无需加密,例如数字和标点符号就不用加密

当前设定加密规则是:循环右移4位,对于输入的字符,只对字母进行加密,字母区分大小写,其他字符例如数字、标点符号等不做加密,直接输出。

提示:字符串处理可以使用C++的string

#include<iostream>
#include<string>
using namespace std;
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		string a;
		cin>>a;
		for(int i=0;i<a.size();i++)
		{
			if(a[i]>='A'&&a[i]<='Z')
			{
				a[i]=a[i]+4;
				if(a[i]>'Z')
				{
					a[i]=a[i]-26;
				}
			}
			else if(a[i]>='a'&&a[i]<='z')
			{
				a[i]=a[i]+4;
				if(a[i]>'z')
				{
					a[i]=a[i]-26;
				}
			}
		}
		cout<<a<<endl;
	}
	return 0;
}

3矩阵转置

题目描述

写一个函数,使给定的一个二维数组(3×3)转置,即行列互换。

输入

一个3x3的矩阵

输出

转置后的矩阵

转置的本质就是:把 a[i][j] 和 a[j][i] 交换

你的困惑很关键:void 函数不 return 任何东西,那它是怎么把转置后的矩阵交给外界的?


答案:通过修改数组本身来实现

你的 transpose 函数直接修改了传入的二维数组 a 的内容。
而数组在 C++ 中是按地址传递的(更准确地说,数组名会退化为指向首元素的指针)。
所以函数里对 a[i][j] 的任何修改,都会直接作用在原数组上,不需要 return 一个值。

#include<iostream>
using namespace std;
void trans(int a[3][3])
{
	for(int i=0;i<3;i++)
	{
		  for(int j=i+1;j<3;j++)//只换上三角:1因为若换两次则相当于没换,不能换下三角;2,对角线可以不用换 
	    {
	      int tem=a[i][j];
		  a[i][j]=a[j][i];
		  a[j][i]=tem;//这样才能实现双方互换! 
	    }
	}
}
int main()
{
    int a[3][3];
    for(int i=0;i<3;i++)
    {
    	for(int j=0;j<3;j++)
    	{
    		cin>>a[i][j];
		}
	}
	trans(a);
	for(int i=0;i<3;i++)
    {
    	for(int j=0;j<3;j++)
    	{
    		cout<<a[i][j];
    		if(j<2)//每三个换一行 
    		{
    			cout<<" ";
			}
	    }
	    cout<<endl;
	}
	return 0;
}

4

题目描述

编写一个函数int substr(char str1[],char str2[],int index),其作用是,将从字符串str1 (长度超过30) 的第index个字符开始的所有字符复制,生成新的字符串str2,如果成功生成,函数返回1,如果不能成功生成,返回0

  • 人类说“第 1 个字符”,指的是字符串开头的第一个。

  • 计算机里,数组位置从 0 开始编号。所以“第 1 个”在计算机里是下标 0,“第 2 个”是下标 1……

公式计算机下标 = 人类的第几个 - 1

getline(cin, a) 和 cin >> t 之间的换行符冲突

你在 cin >> t; 后使用了 getline(cin, a);
但 cin >> t; 会在输入流里留下一个换行符 '\n'getline 一上来会读到一个空行,导致 a 是一个空字符串。

解决方法:在 cin >> t; 后面加一个 cin.ignore(); 吃掉这个换行符。

并且用cin.getline(数组,数组有多少个)

substr 函数没有给 str2 末尾添加 '\0'

字符串必须以 '\0' 结尾,否则输出时会乱码或越界。

解决方法:在复制完字符后手动补一个 '\0'

#include<iostream>
#include<cstring>
using namespace std;
int substr(char str1[],char str2[],int index)
{
	int len=strlen(str1) ;
	if(index>len||index<1)
    {
    	return 0;
	}
	for(int i=0;i<strlen(str1)-index+1;i++)
	{
		str2[i]=str1[index+i];
		
	}
	str2[strlen(str1)-index+1]='\0';
	//如何判断成功与否? 通过对比长度和index
	
	return 1;
}
int main()
{
	int t;
	cin>>t;
	cin.ignore();
	while(t--)
	{
		char a[100]={0};
		char b[100]={0};
		cin.getline(a,100);//数组,个数 
		int index;
		cin>>index;
		cin.ignore();
		if(substr(a,b,index)==1)
		{
			cout<<b<<endl;
		}
		else
		{
			cout<<"IndexError"<<endl;
		}
	}
	return 0;
}

5指针

题目描述

请定义一个基类型为int的指针变量p。

读入一个变量i,若i为0,将p赋值为空;若为1,将p赋值为变量i的地址。

判断该指针变量值是否为空。

若为空输出“NULL”;否则,输出“Initialized”。

⚠️ 易错点

  1. 判断对象错误

    • 题目要求判断指针本身是否为空(p == NULL),而不是指针指向的值(*p == 0)。

    • 如果写成 if (*p == 0),当 i 恰好为 0 时也能输出 "NULL",但这不符合题意:题目是要根据 i 来设置指针的空与非空,再判断指针状态。

✅ 正确逻辑(步骤)

  1. 读入整数 i

  2. 声明指针 int* p = NULL;(安全初始化为空)。

  3. 根据 i 的值设置 p

    • 若 i == 0p = NULL;

    • 否则(题目暗示 i 为 1),p = &i;

  4. 判断指针 p 是否等于 NULL

    • 若 p == NULL,输出 "NULL"

    • 否则,输出 "Initialized"

      #include<iostream>
      using namespace std;
      int main()
      {
      	int* p=NULL;
      	int i;
      	cin>>i;
      	if(i==0)
      	{
      		p=NULL;
      		cout<<"NULL"<<endl;
      	}
      	else
      	{
      		p=&i;
      		cout<<"Initialized"<<endl;
      	}
      	
      	return 0;
      }
      

6动态矩阵

题目描述

未知一个整数矩阵的大小,在程序运行时才会输入矩阵的行数m和列数n

要求使用指针,结合new方法,动态创建一个二维数组,并求出该矩阵的最小值和最大值,可以使用数组下标法。

不能先创建一个超大矩阵,然后只使用矩阵的一部分空间来进行数据访问、

创建的矩阵大小必须和输入的行数m和列数n一样

#include<iostream>
using namespace std;
int main()
{
    //1,输入行列
    int t;
    cin>>t;
    while(t--)
    {
    int n,m;
    cin>>n>>m;
    //2,建立二维数组,new 
    int**a=new int* [n];
    for(int i=0;i<n;i++)
    {
    	a[i]=new int [m];
	}	
	//3,输入二维数组
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			cin>>a[i][j];
		}
	}
    //4,遍历数组得到最大最小值
    int max;
    int min;
    for(int i=0;i<n;i++)
    {
    	for(int j=0;j<m;j++)
    	{
    		if(i==0&&j==0)
    		{
    			max=min=a[0][0];
			}
			else
			{
				if(a[i][j]<min)
				{
					min=a[i][j];
				}
				if(a[i][j]>max)
				{
					max=a[i][j];
				}
			}
		}
	}
    cout<<min<<" "<<max<<endl;
    //6,释放内存 
    for(int i=0;i<n;i++)
    {
    	delete[]a[i];
	}
	delete[]a;
	
    }
    return 0;
}

7常量指针

const int* p;

拆开读:

  • int → 整数

  • * → 指针(存放地址)

  • const 在 * 前面 → 指针指向的那个整数是“只读”的

翻译成人话
p 是一张纸条,上面写着一个门牌号。你拿着纸条可以去那个房间看里面的东西,但不能在房间里乱涂乱画(不能通过 *p 修改值)。
但是,纸条本身可以擦掉重写,让它指向另一个房间(让 p 指向别的变量)。

题目描述

设定以下汇率常量

美元汇率为6.2619,表示1美元兑换6.2619元人民币

欧元汇率为6.6744,表示1欧元兑换6.6744元人民币

日元汇率为0.0516,表示1元日元兑换0.0516元人民币

港币汇率为0.8065,表示1元港币币兑换0.8065元人民币

定义一个常量指针,根据需求指针指向不同的汇率,然后计算出各种货币兑换为人民币的数量

要求:不能直接使用汇率常量进行计算,必须使用常量指针,只能使用一个指针

#include<iostream>
#include<iomanip>//涉及浮点输出小数多少位 
using namespace std;
int main()
{
	//1,输入一个t表示有t个测试实例
	int t;
	cin>>t;
	int t1=t;
	double result=0;
	double a=6.2619;
	double b=6.6744;
	double c=0.0516;
	double d=0.8065;
	while(t--)
	{
	//2, 定义一个常量指针
	const double* p=0;
	//3,输入货币类型和数量
	char type;
	double num;
	cin>>type>>num;
		//4,输出兑换后的人民币数量
		if(type=='D')
		{
			p=&a;
		}
		else if(type=='E')
		{
			p=&b;
		}
		else if(type=='Y')
		{
			p=&c;
		}
		else if(type=='H')
		{
			p=&d;
		}
		result=(*p)*num;
		cout<<fixed<<setprecision(4)<<result<<endl;
		
	}
	
	return 0;
}

8字符串和字符

题目描述

输入一个字符串,判断这个字符串是否一个完全整数值的字符串,例如输入"1234",那么表示整数1234,输入"12a3"就表示只是一个字符串,不是一个整数

要求编写函数isNumber,参数是一个字符指针,返回值是整数类型

如果字符串表示一个整数,则计算出这个整数并且返回

如果字符串不是表示一个整数,则返回-1

主函数必须调用isNumber来判断字符串,不能使用任何C++自带或第三方的类似函数

❌ 错误分析

代码 错误
int isNumber(char* p[]) 参数应为 char* p 或 char s[],不是指针数组
p[i] < '\0' p[i] 是 char*,不能与字符比较
p[i] >= 0 && p[i] <= 9 判断数字字符应写 '0' ~ '9',不是 ASCII 码 0~9
return p 返回类型是 int,却返回指针

✅ 正确逻辑

          正确写法:直接写 isNumber(a)。数组名 a 会自动退化为指向首元素的指针(char*

  1. 遍历字符串每个字符,如果某个字符不是 '0'~'9',直接返回 -1

  2. 如果全部是数字字符,则用“霍纳法则”转换为整数:(char转为int)
    result = result * 10 + (当前字符 - '0')

  3. 返回计算结果。

  4. 不需要处理前导零,因为算法会自动忽略(如 "0012" 会算出 12)。

  5. char* 或 char[] 是字符串(字符数组),可以用 []

  6. 以 isNumber(const char* s) 中的参数 s 虽然写的是 char*,但它指向的是一个字符数组(字符串),自然可以用 s[i] 来遍历每一个字符。
  7. 为什么 isNumber(&a) 类型不对?

    a 是 char[1000]&a 的类型是 char (*)[1000](指向整个数组的指针),不是 char*。函数 isNumber 的参数是 char*,类型不匹配,编译会报错。
    #include<iostream>
    using namespace std;
    //1编写函数isNumber,参数是一个字符指针,返回值是整数类型
    //2字符串表示一个整数,则计算出这个整数并且返回
    //3字符串不是表示一个整数,则返回-1
    int isNumber(char* p)
    {
    	int result=0;
    	for(int i=0;p[i]!='\0';i++)
    	{
    		if(p[i]<'0'||p[i]>'9')
    		{
    		return -1;
    		}
    		else
    		{
    			result=result*10+(p[i]-'0');
    			
    		}
    	}
    	return result; 
    }
    //4输入一个字符串
    int main()
    {
    	int t;
    	cin>>t;
    	char a[1000]={0};
    	while(t--)
    	{
    		cin>>a;
    		cout<<isNumber(a)<<endl;
    	}
    	return 0;
    }
    //5输出 

    8字符串数组

    题目描述

    已知每个月份的英文单词如下,要求创建一个指针数组,数组中的每个指针指向一个月份的英文字符串,要求根据输入的月份数字输出相应的英文单词

    #include<iostream>
    #include<string>
    using namespace std;
    int main()
    {
        string* p[13];
        string a1="January";
        string a2="February";
        string a3="March";
        string a4="April";
        string a5="May";
        string a6="June";
        string a7="July";
        string a8="August";
        string a9="September";
        string a10="October";
        string a11="November";
        string a12="December";
        p[1]=&a1;
        p[2]=&a2;
        p[3]=&a3;
        p[4]=&a4;
        p[5]=&a5;
        p[6]=&a6;
        p[7]=&a7;
        p[8]=&a8;
        p[9]=&a9;
        p[10]=&a10;
        p[11]=&a11;
        p[12]=&a12;
        int t;
        cin>>t;
        while(t--)
        {
        	int num;
        	cin>>num;
        	if(num<1||num>12)
        	{
        		cout<<"error"<<endl;
    		}
    		else
    		{
    			cout<<*p[num]<<endl;
    		}
    	}
        
    	return 0;
    }
    /*string months[12] = {"January", "February", "March", ...};
    for (int i = 0; i < 12; i++) {
        p[i+1] = &months[i];   // p[1]指向January,...
    }*/

    9指针访问数组

    题目描述

    有一种方式是使用密钥进行加密的方法,就是对明文的每个字符使用密钥上对应的密码进行加密,最终得到密文

    例如明文是abcde,密钥是234,那么加密方法就是a对应密钥的2,也就是a偏移2位转化为c;明文b对应密钥的3,就是b偏移3位转化为e,同理c偏移4位转化为g。这时候密钥已经使用完,那么又重头开始使用。因此明文的d对应密钥的2,转化为f,明文的e对应密钥的3转化为h。所以明文abcde,密钥234,经过加密后得到密文是cegfh。

    如果字母偏移的位数超过26个字母范围,则循环偏移,例如字母z偏移2位,就是转化为b,同理字母x偏移5位就是转化为c

    要求:使用三个指针p、q、s分别指向明文、密钥和密文,然后使用指针p和q来访问每个位置的字符,进行加密得到密文存储在指针s指向的位置。

    除了变量定义和输入数据,其他过程都不能使用数组下标法,必须使用三个指针来访问明文、密钥和密文。

    提示:当指针q已经移动到密钥的末尾,但明文仍然没有结束,那么q就跳回密钥头

    #include<iostream>
    #include<cstring>
    using namespace std;
    int main()
    {
    	char* p;
    	char* q;
    	char* s;
    	char a[1000];
    	char b[1000];//数字串也是字符串 
    	char c[1000];
    	int t;
    	cin>>t;
    	while(t--)
    	{
    		
    		cin>>a;
    		cin>>b;
    		p=a;
    		q=b;
    		s=c;
    		while(*p!='\0')
    		{
    			if(*q=='\0')
    			{
    				q=b;
    			}
    				int offset=*q-'0';//数字串转整数
    		if(*p>='a'&&*p<='z') 
    		{
    			*s=(*p-'a'+offset)%26+'a';
    		}
    		else if(*p>='A'&&*p<='Z')
    		{
    			*s=(*p-'A'+offset)%26+'A';
    		}
    		p++;
    		q++;
    		s++;
    		}
    	cout<<c<<endl;
    	}
    	return 0;
    }

    *s = (*p - 'a' + offset) % 26 + 'a'; 的原理

  8. 公式部分 作用 对应的题目要求
    *p - 'a' 将小写字母 'a'~'z' 转换成数字 0~25 方便进行数值偏移计算
    + offset 加上密钥中对应的数字(由 *q - '0' 得到) “每个字符使用密钥上对应的密码进行加密”
    % 26 若加完后的数字 ≥26,则取余数,自动绕回开头 “字母偏移的位数超过26个字母范围,则循环偏移”(例如 z 偏移2位变成 b
    + 'a' 将 0~25 的数字重新转换回小写字母 ASCII 码 得到最终的密文字符,确保是字母
  9. int offset=*q-'0';//数字串转整数

  10. 这一行是把密钥中的数字字符转换成真正的整数。

    题目给的密钥是一个“数字串”,比如 "234",它在程序里实际上是字符 '2''3''4',而不是可以直接运算的整数 2、3、4。

  11. '2' 的 ASCII 码是 50,'0' 的 ASCII 码是 48,相减得到整数 2。

  12. '3' - '0' = 51-48 = 3

  13. '4' - '0' = 52-48 = 4

更多推荐