文章目录
1、前正后负(2018吉林大学941)
一个长度为n的数组由负数、0、正数组成。编写函数,将其重新排列为前段都是负数,后段均为非负数(正数和0都为非负数)的结构。要求时间复杂度为O( n )。
本题的解题思想:
从一个无序的数组变成一个有序的数组,首先想到的是遇到正数和0后移,然后整体前移,遇负数位置不动,但是考虑到时间复杂度O(n),因此只能有一层循环,所以就想到建一个新数组,开始遍历,遇到正数放后面同时后面的指针前移,遇负数方前面同时前面的指针后移,直到将a[n]遍历完成为止。
#include <iostream>
using namespace std;
const int n=10;//const 定义了一个常量
int main()
{
int a[n]={1,-2,-3,4,0,-1,2,3,5,-2};
int b[n];
for(int i=0,j=0,q=0;i<n;i++)//由于主要算法只有一层循环,因此时间复杂度为O(n)
{
if(a[i]<0)//当a[n]中数据<0时,将其放在b[n]的前面,则此时b[n]前面就被占据了一位
{
b[j]=a[i];
j++;
}
else if(a[i]>=0)//当a[n]中数据>=0时,将其放在b[n]的后面,则此时b[n]后面就被占据了一位
{
b[n-1-q]=a[i];//b[n]的下标是从9结尾的,因此要减一,而b[n]后面被占据了一位,因此要b[n-1-p]
q++;
}
}
cout<<"原序列为:"<<endl;
for(int i=0;i<n;i++)
{
cout<<a[i]<<",";
}
cout<<endl<<"排序后的序列为:"<<endl;
for(int i=0;i<n;i++)
{
cout<<b[i]<<",";
}
return 0;
}
2、买卖青蛙(股票求利润最大)
你现在是一个买卖青蛙的huster。每天的青蛙价格不一样,prices[i]代表青蛙在第i天的价格,求只做一次交易(买入1只,卖出1只)能得到的最大收益(必须先买了青蛙之后再卖出青蛙)。
时间复杂度要求:O(n)
函数:int maxincome(int prices[ ],int n)
例如:第一天售价4元,第二天售价1元,第三天售价2元,第四天售价3元。则最聪明的做法是第二天1元买入,第四天3元卖出。
输出:
i 0 1 2 3
prices[i] 4 1 2 3
输出: 2
思路:
从前向后扫描,假设就在扫描到的那一天进行出售
则可以知道,要想利润最大,买的那一天一定是价格最低的,
所以用当前天的出售的价格去减去当前最低价格就是当前最优解,
如果这个解比上一步得到的结果更好则进行更新全局最优解
#include<iostream>
#define MIN 0xc0c0c0c0
#define MAX 0x3f3f3f3f
using namespace std;
int MostProfit(int data[], int n)
{
int minPrice = MAX;
int maxProfit = MIN;
for(int i = 0; i < n; i++)
{
if(data[i] < minPrice)
{
minPrice = data[i];
}
if(data[i] - minPrice > maxProfit)
{
maxProfit = data[i] - minPrice;
}
}
return maxProfit;
}
int main()
{
int data[1000],n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>data[i];
}
int maxProfit;
maxProfit = MostProfit(data, n);
cout<<"最大利润为:"<<maxProfit<<endl;
return 0;
}
3、单词个数统计(2019华科软院学硕上机(一))
从键盘输入一行字符,长度小于1000,统计其中单词的个数,每个单词以空格分隔,且空格数可以是多个。
输入样例:
To be or not to be This is a ques
tion
输出样例:
10
注释部分为将逗号计入字符串
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int main()
{
vector<string> s;
string temp;
//出现逗号 int count=0
while(cin>>temp)
{
//判断逗号 if(temp.find(',')!=string::npos)
// count++
s.push_back(temp);
if(cin.get()=='\n')
{
break;
}
}
cout<<s.size();
//最后的结果加上逗号的数量 count<<s.size()+count;
return 0;
}
从本段代码学到的知识:
(1)引用string类型的数据,需要调用相应的头文件即 #include< string >
(2)若想使用vector方法就要调用相应的头文件即 #include< vector >
vector就是类似于一个数组的容器,内容比数组更加全面。很多操作都有自己的函数可以直接拿过来进行使用。主要函数就是:
v.push_back(k); 尾插元素;
v.insert(it,k); 在任意位置插入元素;
v.eraser(it,it+k); 删除任意元素;
v.size(); 容量;
v.clear(); 清空容器;
v.empty(); 判断容器是否为空;
reverse(v.begin(),v.end());反转任意段元素
使用方法 ,例:
vector< string> ff; // string对象作为vector对象 ,可以调用vector方法
ff.push_back(“Jack”);
(3)vector方法中,往string类型的容器s中添加元素的固定模板
while(cin>>temp)
{
s.push_back(temp);
}
(4)cin.get()代表输入的元素
if(cin.get()==’\n’) 如果输入的元素为回车则退出循环
break;
(5)s.size(); 统计容器s的大小,不是单独的字符而是统计分隔的字符串
(6)if(temp.find(’,’)!=string::npos) 查询temp字符串中是否包含子串‘,’
4、魔方阵(2019华科软院学硕上机(二))没有搞明白
魔方阵,古代又称“纵横图”,是指组成元素为自然数1、2…n的平方的n×n的方阵,其中每个元素值都不相等,且每行、每列以及主、副对角线上各n个元素之和都相等。阶数大于等于3。
如3×3的魔方阵:
8 1 6
3 5 7
4 9 2
奇数魔方阵的排列规律如下:
(1)将1放在第一行中间一列;
(2)从2开始直到n×n止各数依次按下列规则存放;每一个数存放的行比前一个数的行数减1,列数加1(例如上面的三阶魔方阵,5在4的上一行后一列);
(3)如果上一个数的行数为1,则下一个数的行数为n(指最下一行);例如1在第一行,则2应放在最下一行,列数同样加1;
(4)当上一个数的列数为n时,下一个数的列数应为1,行数减去1。例如2在第3行最后一列,则3应放在第二行第一列;
(5)如果按上面规则确定的位置上已有数,或上一个数是第一行第n列时,则把下一个数放在上一个数的下面。例如按上面的规定,4应该放在第1行第2列,但该位置已经被占据,所以4就放在3的下面;
输入格式:
输入魔方阵的阶数(阶数大于等于3的奇数阵)
输出格式:
输出魔方阵
输入样例:3
输出样式 8 1 6
3 5 7
4 9 2
#include<iostream>
#include<vector>
#include<iomanip>
using namespace std;
int main()
{
int n;
cin>>n;
getchar();
vector<vector<int>> f(n);
for(int i=0;i<f.size();i++)
{
f[i].resize(n);
}
int r=0,c=n/2;
f[r][c]=1;
for(int i=2;i<=n*n;i++)
{
if((r==0)&&(c==n-1))
{
f[++r][c]=i;
continue;
}
if(r==0)
{
r=n-1;
c++;
f[r][c]=i;
comtinue;
}
}
}
5、比较大小(2019年天津大学计算机上机(一))
输入由一行整数构成的数组,输出数组中小于此整数的数字的个数。
输入格式:
第一行:先输入数组元素的个数N(<1000000),测试用例数M;
第二行:输入数组,以空格隔开;
输出格式:
小于给定M的数字的个数
输入样例:
7 5
1 4 3 9 5 6 6
输出样例:
3
个人的做法
#include<iostream>
using namespace std;
int main()
{
int N,M,n;
cin>>N;
cin>>M;
int a[N];
for(int i=0;i<N;i++)
{
cin>>n;
a[i]=n;
}
int m=0;
for(int i=0;i<N;i++)
{
if(a[i]<M)
{
m++;
}
}
cout<<m<<endl;
return 0;
}
简单做法
#include<iostream>
using namespace std;
int main()
{
int N,M;
cin>>N>>M;
int count=0,n;
for(int i=0;i<N;i++)
{
cin>>n;
if(n<M)
count++;
}
cout<<count;
return 0;
}
简单的做法是其实就是在输入时没有引入数组,而是直接的输入一个数据就比较一个数据,而不是像数组那样先整体输入,再整体比较。
6、十进制转换为八进制(2019年天津大学计算机上机(二))
十进制转换为八进制
输入格式:
十进制数字
输出格式:
八进制数字
输入样例:
150
输出样例:
226
如何将十进制转化为八进制?
#include<iostream>
using namespace std;
int main()
{
long a;
int n;
cin>>a>>n;
int y[100]={0};
y[0]=a%n;
int s=a/n;
if(s==0)
{
cout<<y[0];
return 0;
}
int i=0;
while(s!=0)
{
i++;
y[i]=s%n;
s=s/n;
}
i++;
while(i--)
{
cout<<y[i];
}
return 0;
}
从本代码学到的知识点
1、十进制转换为八进制
2、long表示为长整型
短整型的二进制位长是16,长整型的是32位。就是说长整型可以表示位数更多的整数。短整型所能表示的整数的值域为-32768~32767。
长整型则为-2147483648~2147483647。例如,如果有个数为32780,那么它只能用长整型表示,而不能用短整型表示。
7、水仙花数(东华大学上机题(一))
写一个程序,该程序的功能是输出100到999之间的所有水仙花数。水仙花数的特点是:它的每个位数上的数字的三次幂之和等于它本身。
例如:371=3^ 3+7 ^3+1 ^3,因此371是水仙花数。
输出样例:
153 370 371 407
#include<iostream>
using namespace std;
void findWaterFlowerNum()
{
int ge=0,shi=0,bai=0;
for(int i=100;i<999;i++)
{
ge=i%10;
int n=i/10;
shi=n%10;
bai=n/10;
if(ge*ge*ge+shi*shi*shi+bai*bai*bai==1)
{
cout<<i<<" ";
}
}
cout<<endl;
}
int main()
{
findWaterFlowerNum();
system("pause");
return 0;
}