本文是在学校开题了练习系统之后,可以免费白嫖这个系统,然后根据这个系统的习题顺序而写的答案和个人解析。
目录
基础练习
十六进制转八进制
思路:16进制转2进制,2进制转8进制。
注意事项:
16进制转2可以利用一个数组,对16进制数相减得到二进制数。
2转8利用哈希表是为了方便我们取3个二进制数构成一位8进制数之后,找到该8进制数是多少。
需要去掉最开始的0
#include<bits/stdc++.h>
using namespace std;
//定义16进制
string h[16] = { "0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111" };
unordered_map<string, char>u_map;
//16转2
string fun16(string s) {
string ans = "";
int len = s.size();
for (int i = 0; i < len; i++) {
if (s[i] >= '0' && s[i] <= '9') {
//判断是0-9或者A-E。求得在16进制数组中的数,例如输入字符串是2,得到0010
ans += h[s[i] - '0'];
}
else {
ans += h[s[i] - 'A' + 10];
}
}
return ans;
}
//2转8
string fun8(string s) {
string ans = "";
int len = s.size();
//len的长度如果不满足3,则需要补位,补位是在最前面补0
if (!(len % 3 == 0)) {
int a = 3 - (len % 3);
while (a--)
{
s = '0' + s;
}
}
//根据补0之后,每3位取一次
for (int i = 0; i < len; i += 3) {
ans += u_map[s.substr(i, 3)];
}
return ans;
}
//去第一位0
string fun0(string s) {
//如果s是有非0的字符串,且第一位是0,例如八进制 043这种,则变为43
while (s.size() && s[0] == '0') {
s = s.substr(1);
}
return s;
}
int main()
{
//二进制和八进制转换的map
u_map["000"] = '0', u_map["001"] = '1', u_map["010"] = '2', u_map["011"] = '3', u_map["100"] = '4', u_map["101"] = '5', u_map["110"] = '6', u_map["111"] = '7';
int n;
cin >> n;
for (int i = 0; i < n; i++) {
string s;
cin >> s;
string temp1 = fun16(s);
string temp2 = fun8(temp1);
string ans = fun0(temp2);
cout << ans << endl;
}
return 0;
}
十六进制转十进制
思路:16进制每一位直接根据A=10,B=11进行转换,然后利用pow根据位数求得结果。
注意事项:
16进制每一位的转换根据switch转换。
字符串从最高位开始,取pow的时候比较方便。
#include<iostream>
#include<math.h>
using namespace std;
int main()
{
string str;
int temp;
cin >> str;
long long sum = 0;
int len = str.size() - 1;
//通过遍历字符串获取每一位,然后根据每一位去计算这个值
for (int i = 0; i < str.size();i++) {
switch (str[i])
{
case 'A': temp = 10; break;
case 'B': temp = 11; break;
case 'C': temp = 12; break;
case 'D': temp = 13; break;
case 'E': temp = 14; break;
case 'F': temp = 15; break;
// 针对数字0-9
default: temp = str[i] - '0'; break;
}
//由于是从第一位开始的,所以是最高位,直接取pow
sum += temp * pow(16, len);
len -= 1;
}
cout << sum;
return 0;
}
十进制转十六进制
思路:对输入数据进行模16,取得最低位,然后除16取得现在剩多少,再重复进行
注意事项:
取得最低位的时候是整型对16取模还是整型,此时需要根据一个数组对应把该值转为十六进制对应的值。
#include<iostream>
using namespace std;
int main()
{
char ans[10],k=0;
char a[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
long long int num;
cin>>num;
if(num==0){
cout<<0<<endl;
}else{
while(num){
ans[k++]=a[num%16];
num /= 16;
}
for(int i=k-1;i>=0;i--){
cout<<ans[i];
}
}
return 0;
}
特殊回文数
思路:由于已经确定回文数最长就是6位数或者5位数。按6位数举例,必须是abccba这种形式的数,那么就可以判断2*(a+b+c)=num,如果满足则找到了回文数
注意事项:
1.输出有两种形式
#include<iostream>
using namespace std;
int main()
{
int num;
cin>>num;
//5位数
for(int i=1;i<=9;i++){
for(int j=0; j<=9;j++){
for(int k=0; k<=9;k++){
if(2*(i+j)+k==num){
cout<<i*10001+j*1010+k*100<<endl;
//cout<<i<<j<<k<<j<<i<<endl;
}
}
}
}
//6位数
for(int i=1;i<=9;i++){
for(int j=0; j<=9;j++){
for(int k=0; k<=9;k++){
if(2*(i+j+k)==num){
cout<<i*100001+j*10010+k*1100<<endl;
//cout<<i<<j<<k<<k<<j<<i<<endl;
}
}
}
}
return 0;
}
回文数
思路:由于确定是4位整型,那么只需要遍历1000到9999.满足abba形式即可
注意事项:
1.对数据进行除模运算求得每一位的值
2.判断是不是回文数判断满不满足abba
#include<iostream>
using namespace std;
int main()
{
for(int i=1000;i<=9999;i++){
int a = i /1000 % 10;
int b = i / 100 % 10;
int c = i / 10 % 10;
int d = i % 10;
if(a==d && b==c){
cout<<a<<b<<c<<d<<endl;
}
}
return 0;
}
特殊的数字
思路:遍历100-999,判断满足aaa+bbb+ccc=num
注意事项:
1.对每一位的数字采用除模取得
#include<iostream>
using namespace std;
int main()
{
for(int i=100;i<=999;i++){
int a= i / 100;
int b = i / 10 % 10;
int c = i % 10;
if(a*a*a + b*b*b + c*c*c == i){
cout<<i<<endl;
}
}
return 0;
}
杨辉三角形
思路:ans[a][a]一直为1,且第一列一直为1,其他ans[a][b]=ans[a-1][b-1]+ans[a-1][b]
注意事项:
1.两个for循环的时候,i和j的设置是因为每一行数字都是1x1,2x2,nxn这种
#include<iostream>
using namespace std;
int main()
{
int num;
cin>>num;
int ans[num][num];
for(int i = 0; i < num; i++){
for(int j = 0; j < i + 1; j++){
if(j==i){
ans[i][j]=1;
cout<<"1 "<<endl;
}
else if(j==0){
ans[i][j]=1;
cout<<"1 ";
}else{
ans[i][j]=ans[i-1][j-1] + ans[i-1][j];
cout<<ans[i][j]<<' ';
}
}
}
return 0;
}
查找整数
思路:插入元素,然后遍历
注意事项:
1.插入重复元素可以去掉节省空间复杂度
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n, m,target, ans[1000];
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> m;
ans[i] = m;
}
cin >> target;
for (int i = 0; i < n; i++)
{
if (ans[i] == target)
{
cout << i + 1;
return 0;
}
}
cout<<-1;
return 0;
}
数列特征
思路:对数组排序即可得到最大最小
注意事项:
1.利用sort排序
2.利用accumulate求和,其头文件是numeric
#include<iostream>
#include<algorithm>
#include<numeric>
#include<vector>
using namespace std;
int main()
{
int n, m;
long int ans = 0;
vector<int>vec;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> m;
vec.push_back(m);
}
sort(vec.begin(), vec.end());
ans = accumulate(vec.begin(),vec.end(),0);
cout << vec[n - 1] << endl;
cout << vec[0] << endl;
cout << ans << endl;
return 0;
}
字母图形
思路:先取得第一行,然后按顺序取后面行,每一行需要两个判断,一个是在上一行基础上加1,一个是减1.
注意事项:
1.利用’A‘+1得到B
2.第一行求了之后,后续for不需要管第一行了
#include<iostream>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
char ans[26][26];
for(int j=0;j<m;j++)
{
ans[0][j]='A'+j; //先表示出第一行的各元素
}
//每次求一行
for(int i=1;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(i<=j){
ans[i][j]=ans[i-1][j]-1;
}else{
ans[i][j]=ans[i-1][j]+1;
}
}
}
//输出数组
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cout<<ans[i][j];
}
cout<<endl;
}
return 0;
}
01字串
思路:把10进制转2进制,然后输出
注意事项:
1.利用对2取模判断是0还是1,得到每一位结果
2.对当前的结果长度判断,在前面补零
#include<iostream>
#include<algorithm>
using namespace std;
string DecToBin(int n){
string str[2]={"0","1"};
string ans ="";
if(n==0){
return ans+"0";
}
while(n){
ans=str[n%2]+ans;
n /= 2;
}
return ans;
}
int main()
{
for(int i=0;i<32;i++){
string str = DecToBin(i);
switch(str.size()){
case 1:
str = "0000"+str;
break;
case 2:
str = "000"+str;
break;
case 3:
str = "00"+str;
break;
case 4:
str = "0"+str;
break;
}
cout<<str<<endl;
}
return 0;
}
闰年判断
思路:安装题目要求判断
注意事项:
1.无
#include<iostream>
using namespace std;
int main()
{
int year;
cin>>year;
if((year%4==0 && year %100!=0)||year%400==0){
cout<<"yes"<<endl;
}else{
cout<<"no"<<endl;
}
return 0;
}
圆的面积
思路:直接利用公式求圆面积
注意事项:
1.#include <iomanip>提供小数保留
2.#include<math.h>提供求Π
#include<iostream>
#include<math.h>
#include <iomanip>
using namespace std;
const double PI=atan(1.0)*4;
int main(){
int r;
cin>>r;
double s;
s = PI*r*r;
cout<<setiosflags(ios::fixed)<<setprecision(7)<<s<<endl;
return 0;
}
序列求和
思路:等差求和
注意事项:
1.输入n要为long long int
#include<iostream>
using namespace std;
int main()
{
long long int n;
cin>>n;
long long int ans = n*(1+n)/2;
cout<<ans<<endl;
return 0;
}
Fibonacci数列
思路:利用Fn=Fn-1+Fn-2计算
注意事项:
1.数组存放元素是余数更简单
#include<iostream>
using namespace std;
int main()
{
long int n;
cin>>n;
int ans[n];
for(int i =1;i<=n;i++){
if(i==1 || i==2){
ans[i]=1;
}else{
ans[i]=(ans[i-1]+ans[i-2])%10007;
}
}
cout<<ans[n];
return 0;
}
阶层计算
思路:根据一个“固定算法”得到值之后,按照数组输出顺序进行输出
注意事项:
1.按固定写法即可
2.数组大小要1000,不能1000
3.输出的时候注意是先输出大的,因此先输出数组最后的值
4.要判断数组最后的有效值在哪里
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int ans[10000]={0};
ans[0]=1;
for(int i=1;i<=n;i++){
int count =0;
for(int j=0;j<10000;j++){
ans[j]=ans[j]*i+count;
count = ans[j]/10;
ans[j] = ans[j]%10;
}
}
int end;
for(int i=10000-1;i>=0;i--){
if(ans[i]!=0){
end=i;
break;
}
}
for(int i=end;i>=0;i--){
cout<<ans[i];
}
return 0;
}
高精度加法
思路:把两个字符串存入数组中,然后对两个数组进行相加得到结果
注意事项:
1.字符串存入数组时,需要按从低位到高位顺序,因为一会儿要从小往上加
2.进位的时候需要注意没有进位则清0
3.输出的时候注意顺序
#include<iostream>
using namespace std;
int main()
{
int A[100] = { 0 }, B[100] = { 0 },C[100]={0};
int flag = 0;
string a, b;
cin >> a >> b;
for (int i = a.size()-1,j=0; i >=0; i--,j++) {
A[j] = a[i] - '0';
}
for (int i = b.size() - 1, j = 0; i >= 0; i--, j++) {
B[j] = b[i] - '0';
}
for (int i = 0; i < 100; i++) {
C[i] = A[i] + B[i] + flag;
if (C[i] >= 10) {
flag = C[i] / 10;
C[i] %= 10;
}
else {
flag = 0;
}
}
int end;
for (int i = 99; i > 0; i--) {
if (C[i] != 0) {
end = i;
break;
}
}
for (int i = end; i >=0; i--) {
cout << C[i];
}
return 0;
}
Huffuman树
思路:用数组存放元素之后,对齐排序,把a【0】和a【1】两个值加起来得到第一次sum,然后把得到的sum赋值给给a【1】,然后对a【1】-a【end】排序,再把a【2】和a【3】加起来,以此类推。
注意事项:
1.数组定义大一点且值为0,防止最后数组下标溢出
2.每次都抛弃排序数组后第一个元素
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int ans[102]={0};
int n,num;
int sum = 0;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> num;
ans[i] = num;
}
sort(ans+0, ans + n);
int index = 0;
while (index < n-1) {
sum += ans[index] + ans[index + 1];
ans[index+1] = ans[index] + ans[index + 1];
index++;
sort(ans + index, ans + n);
}
cout << sum;
return 0;
}
2n皇后问题
报时助手
思路:对数字进行模除运算得到各个位,如果小于等于20则按下标输出,否则判断一下
注意事项:利用min和sec判断而不是余数判断更简单
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
string str[] = { "zero" ,"one","two" ,"three", "four" ,"five","six" ,"seven", \
"eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", \
"sixteen", "seventeen", "eighteen", "nineteen", "twenty", \
"thirty ", "forty", "fifty"
};
int min, sec;
cin >> min >> sec;
int temp1 = min / 10;
int temp2 = min % 10;
int temp3 = sec / 10;
int temp4 = sec % 10;
if (min > 20 ) {
//20-59,没有30,40,50
cout << str[temp1+18] << ' ' << str[temp2] << ' ';
}
else {
cout << str[min] << ' ';
}
//判断个位
if (sec > 20) {
//20-59,没有30,40,50
cout << str[temp3 + 18] << ' ' << str[temp4] << ' ';
}
else if (sec <= 20 && sec>0) {
cout << str[sec] << ' ';
}
else {
cout << "o'clock";
}
return 0;
}
回形取数
思路:通过标记数组,每次按照,上下左右进行移动
注意事项:
1.不担心重复输出问题,因为有标记数组
2.也不用担心回到了起始列而不在应该出现的列,因为有标记数组
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 205;
int a[N][N];
int vis[N][N] = { 0 }; //初始化,数组里面都没有数字
int main() {
int n, m;
cin >> m >> n;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
cin >> a[i][j];
vis[i][j] = 1; //数组里有数字的标记为1
}
}
cout << a[0][0]; vis[0][0] = 0;//输出第一个并标记
int tot = 1, i = 1, j = 0; //tot为要输出的总个数,a[i][j],为第i行第j列
while (m * n > tot) {
//1.上往下
while (i < m && vis[i][j] == 1) {
cout << " " << a[i][j];
vis[i][j] = 0; //已经输出过的标记为0
i++; tot++;
}
i--; j++; //因为下一次是从下一列开始,那么j++,而当前i超出数组,所以--
//2.左往右
while (j < n && vis[i][j] == 1) {
cout << " " << a[i][j];
vis[i][j] = 0;
j++; tot++;
}
i--; j--;
//3.下往上
while (i >= 0 && vis[i][j] == 1) {
cout << " " << a[i][j];
vis[i][j] = 0;
i--; tot++;
}
i++; j--;
//右往左
while (j >= 0 && vis[i][j] == 1) {
cout << " " << a[i][j];
vis[i][j] = 0;
j--; tot++;
}
j++; i++;
}
return 0;
}
龟兔赛跑预测
思路:龟兔进行跑步,保证两个人时间一样,看谁先跑到终点,当兔子懒惰时,直接后退
注意事项:
1.当有一方超过终点时,比较此时两人跑的距离,谁远谁赢
2.输出时间是一样的,也就是记录的时间下标index
// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
using namespace std;
int main()
{
int v1, v2, t, s, l, s1, s2,index;
cin >> v1 >> v2 >> t >> s >> l;
s1 = 0, s2 = 0,index=0;
while (s1 < l && s2 < l) {
s1 += v1;
s2 += v2;
index++;
if (s1 == l || s2 == l) {
//有一个到终点了
break;
}
if (s1 - s2 >= t) {
//当兔子超过乌龟后,直接休息s秒,相当于兔子退后s*v1这么远
s1 -= v1 * s;
}
}
if (s1 > s2) {
cout << "R"<<endl;
}
else if (s1 < s2) {
cout << "T"<<endl;
}
else {
cout << "D" << endl;
}
cout << index;
}
芯片测试
思路:对每个被测芯片求它有多少个1,如果1的个数大于0的个数,那么该芯片是好的
注意事项:
1.本代码有一个没过
// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int num[30][30]={0};
int temp;
//存入数据
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> temp;
num[i][j] = temp;
}
}
int ans[n];
//计算每个芯片被测了多少个1
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i != j && num[i][j] == 1) {
ans[j]++;
}
}
}
for (int i = 0; i < n; i++) {
if (ans[i] >= n / 2) {
cout << i + 1<<' ';
}
}
return 0;
}
FJ数列
不会递归
#include <iostream>
using namespace std;
char c[] = { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' };
void A(int n)
{
if (n == 1)
{
cout << "A";
}
else
{
A(n - 1);
cout << c[n - 1];
A(n - 1);
}
}
int main()
{
int n;
cin >> n;
A(n);
return 0;
}
Sine之舞
不会递归
#include <iostream>
#include<string>
using namespace std;
string num;
string num1;
string An(int i, int j, int n)
/*因为每一次这是按照从小到大的顺序,所以要变量j,也可以直接全写成数字1*/
{
/*string num1 = "0" + j;
string num1 = '0' + j; */ /*错误*/
/*num1 = "0" + j;*/
/*也可以如下表示*/
num1 = '0' + j;
string str1 = "sin(" + num1;
/*因为c++中当进行string对象和字符串字面值混合连接操作时,
+ 操作符的左右操作数必须至少有一个是string类型的*/
if (i == n)
{
return str1 + ')';
}
if (j % 2 == 0)
{
return str1 + '+' + An(i + 1, j + 1, n) + ')';
}
else
{
return str1 + '-' + An(i + 1, j + 1, n) + ')';
}
}
string Sn(int i, int j, int n)
{
num = '0' + i;
string str1 = "+" + num;
if (i == n)
{
return An(i, j, n) + str1;
}
else {
return '(' + Sn(i + 1, j, n) + ')' + An(i, j, n) + str1;
}
}
int main()
{
int N;
cin >> N;
int i = 1;
int j = 1;
string Sine = Sn(i, j, N);
cout << Sine << endl;
return 0;
}
数的读法
#include <iostream>
using namespace std;
int main()
{
string str;
cin >> str;
string a[10] = { "ling","yi","er","san","si","wu","liu","qi","ba","jiu" };
string b[10] = { "","shi","bai","qian","wan","shi","bai","qian","yi","shi" };
int len = str.length();//求输入数的位数
for (int i = 0; i < str.length(); i++)
{
int flag = str[i] - '0';//求每一位数值,如输入123,flag的值依次为1,2,3
if (flag == 0)//对于是0的数的读法进行讨论,参考分析3
{
if (len - i == 5 || len - i == 9)
cout << b[len - i - 1] << " ";
if ((len - i) != 1 && str[i + 1] != '0')
cout << "ling ";
}
else if ((len == 2 || len == 6 || len == 10) && flag == 1 && i == 0)//对数字出现的10,是读yi shi 还是读 shi 进行分析,参考分析4
{
cout << "shi ";
}
else//其他直接读出数和数的对应单位即可
cout << a[flag] << " " << b[len - i - 1] << " ";
}
return 0;
}
分解质因素
思路:先判断是不是素数,是则直接输出x=x,不是素数,则先除2,除3,除4这样依次计算,直到x=1
注意事项:
1.math.h库而不是algorithm库
2.里面用了if(!【】),表示【】=0则满足if
#include<iostream>
#include<algorithm>
using namespace std;
//判断是不是素数
int isPrime(int n) {
if (n == 1)
return 1;
else {
for (int i = 2; i <= sqrt(n); i++) {
if (!(n % i))//=0则满足条件
return 0;
}
return 1;
}
}
int main()
{
int a, b;
cin >> a >> b;
for (int i = a; i <= b; i++) {
if (isPrime(i)) {
cout << i << "=" << i << endl;
}
else {
cout << i << "=";
int temp = i;
int j = 2;
while (temp > 1) {
if (!(temp % j)) {
temp = temp / j;
cout << j;
if (temp != 1) {
cout << "*";
}
}
else {
j++;
}
}
cout << endl;
}
}
return 0;
}
字符串对比
思路:第一种:判断大小,第二种,直接“==”,第三种,用ASCALL,第四种则不满足第三种
注意事项:
1.a:97,A:65
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
string str1, str2;
cin >> str1 >> str2;
int str1Len = str1.size();
int str2Len = str2.size();
//第一种 a97 A65
if (str1Len != str2Len) {
cout << 1;
}
if (str1Len == str2Len && str1 == str2) {
cout << 2;
return 0;
}
if (str1Len == str2Len && str1 != str2) {
for (int i = 0,j=0; i < str1.size(),j<str2.size();j++, i++) {
if (str1[i] != str2[j]) {
if (str1[i] == str2[j] + 32 || str2[j] == str1[i] + 32) {
cout << 3;
return 0;
}
else {
cout << 4;
return 0;
}
}
}
}
return 0;
}
时间转换
思路:对时间的小时,分钟,秒分别进行模余运算
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int num;
cin >> num;
int hour = 0, min = 0, miao = 0;
hour = num / 3600;
min = num % 3600 / 60;
miao = num % 3600 % 60;
cout << hour << ":" << min << ":" << miao << endl;
return 0;
}
来不及了,要写真题了,鸽了