机试编程(九)
目录:
- 应用实例
- 奇偶校验【华中科技大学】
- 互换最大最小数【哈尔滨工业大学】
- 查找【北京邮电大学】
- 田忌赛马 Tian Ji -- The Horse Racing【hdu 1052】
- 众数【哈尔滨工业大学】
- 整数和【北京理工大学】
- 完数【哈尔滨工业大学】
- 判断三角形类型【哈尔滨工业大学】
- 单词识别【北京理工大学】
- 学分绩点【北京大学】
- 百万富翁【哈尔滨工业大学】
- 买房子【北京大学】
- 合并符串【西北工业大学】
- 分段函数【北京理工大学】
- 买卖股票【LeetCode 121】
- 最佳买卖股票时机含冷冻期【LeetCode 309】
- 买卖股票的最佳时机含手续费【LeetCode 714】
- 山脉数组中查找目标值【LeetCode 1095】
- C翻转【北京邮电大学】
- 阶乘【北京理工大学】
一、应用实例:
1、题目描述:输入一个字符串,然后对每个字符进行奇校验,最后输出校验后的二进制数(如'3’,输出:10110011)。【华中科技大学】
- 输入格式:输入包括一个字符串,字符串长度不超过100。
- 输出格式:可能有多组测试数据,对于每组数据,对于字符串中的每一个字符,输出按题目进行奇偶校验后的数,每个字符校验的结果占一行。
- 样例输入:
- 3
- 3a
- 样例输出:
- 10110011
- 10110011
- 01100001
示例代码:
#include <iostream>
#include <string>
using namespace std;
const int LEN = 8;
string GetBinary(int n, int &sum){
string result;
int tmp;
while(n != 0){
tmp = n % 2;
if(tmp == 1){
sum++;
}
result += tmp + '0';
n /= 2;
}
while(result.size() < LEN){
result += '0';
}
return result;
}
int main(){
string s;
while(cin >> s){
string result;
int count;
for(int i = 0; i < s.size(); i++){
count = 0;
result = GetBinary(s[i], count);
if(count % 2 == 0){
result[LEN - 1] = '1';
}
for(int j = LEN - 1; j >= 0; j--){
cout << result[j];
}
cout << endl;
}
}
return 0;
}
附注:
(1)对其ASCII码值进行奇校验,若二进制表示中有奇数个1则正确,若是偶数个1则应添加一个1使其含奇数个1。当要补1时,在最高位上补。0:48,A:65,a:97
2、题目描述:输入一个数n,然后输入n个数值各不相同,调换数组中最大和最小的两个数,然后输出。【哈尔滨工业大学】
- 输入格式:测试数据有多组,输入n(1<=n<=20),接着输入n个数。
- 输出格式:对于每组输入,输出交换后的结果。
- 样例输入:
- 2
- 1 3
- 样例输出:
- 3 1
示例代码:
#include <iostream>
using namespace std;
const int MAX_INT = 0x7fffffff;
const int MIN_INT = -0x7fffffff;
int a[21];
int main(){
int n;
while(cin >> n){
int maxValue = MIN_INT, minValue = MAX_INT, maxLoc, minLoc;
for(int i = 0; i < n; i++){
cin >> a[i];
if(a[i] > maxValue){
maxValue = a[i];
maxLoc = i;
}
if(a[i] < minValue){
minValue = a[i];
minLoc = i;
}
}
a[minLoc] = maxValue;
a[maxLoc] = minValue;
bool flag = false;
for(int i = 0; i < n; i++){
if(flag){
cout << " ";
}
flag = true;
cout << a[i];
}
cout << endl;
}
return 0;
}
3、题目描述:读入一组字符串(待操作的),再读入一个int n记录记下来有几条命令,总共有2种命令:1、翻转 从下标为i的字符开始到i+len-1之间的字符串倒序;2、替换 命中如果第一位为1,用命令的第四位开始到最后的字符串替换原读入的字符串下标 i 到 i+len-1的字符串。每次执行一条命令后新的字符串代替旧的字符串(即下一条命令在作用在得到的新字符串上)。 命令格式:第一位0代表翻转,1代表替换;第二位代表待操作的字符串的起始下标int i;第三位表示需要操作的字符串长度int len。【北京邮电大学】
- 输入格式:输入有多组数据。每组输入一个字符串(不大于100)然后输入n,再输入n条指令(指令一定有效)。
- 输出格式:根据指令对字符串操作后输出结果。
- 样例输入:
- bac
- 2
- 003
- 112as
- 样例输出:
- cab
- cas
示例代码:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main(){
string s, orderStr, beginStr, endStr;
int orderNum;
int begin, len;
while(cin >> s >> orderNum){
for(int i = 0; i < orderNum; i++){
cin >> orderStr;
begin = orderStr[1] - '0';
len = orderStr[2] - '0';
beginStr = s.substr(0, begin);
endStr = s.substr(begin + len);
if(orderStr[0] == '0'){ //翻转
string revStr = s.substr(begin, len);
reverse(revStr.begin(), revStr.end());
s = beginStr + revStr + endStr;
}else{ //替换
int index;
s = beginStr;
for(index = 3; index < orderStr.size(); index++){
s += orderStr[index];
}
if(index < orderStr.size()){
s += orderStr[index++];
}
s += endStr;
}
cout << s << endl;
}
}
return 0;
}
4、题目描述:Here is a famous story in Chinese history."That was about 2300 years ago. General Tian Ji was a high official in the country Qi. He likes to play horse racing with the king and others.""Both of Tian and the king have three horses in different classes, namely, regular, plus, and super. The rule is to have three rounds in a match; each of the horses must be used in one round. The winner of a single round takes two hundred silver dollars from the loser.""Being the most powerful man in the country, the king has so nice horses that in each class his horse is better than Tian's. As a result, each time the king takes six hundred silver dollars from Tian.""Tian Ji was not happy about that, until he met Sun Bin, one of the most famous generals in Chinese history. Using a little trick due to Sun, Tian Ji brought home two hundred silver dollars and such a grace in the next match.""It was a rather simple trick. Using his regular class horse race against the super class from the king, they will certainly lose that round. But then his plus beat the king's regular, and his super beat the king's plus. What a simple trick. And how do you think of Tian Ji, the high ranked official in China?"
Were Tian Ji lives in nowadays, he will certainly laugh at himself. Even more, were he sitting in the ACM contest right now, he may discover that the horse racing problem can be simply viewed as finding the maximum matching in a bipartite graph. Draw Tian's horses on one side, and the king's horses on the other. Whenever one of Tian's horses can beat one from the king, we draw an edge between them, meaning we wish to establish this pair. Then, the problem of winning as many rounds as possible is just to find the maximum matching in this graph. If there are ties, the problem becomes more complicated, he needs to assign weights 0, 1, or -1 to all the possible edges, and find a maximum weighted perfect matching...
However, the horse racing problem is a very special case of bipartite matching. The graph is decided by the speed of the horses --- a vertex of higher speed always beat a vertex of lower speed. In this case, the weighted bipartite matching algorithm is a too advanced tool to deal with the problem.
In this problem, you are asked to write a program to solve this special case of matching problem.【hdu 1052】
- 输入格式:The input consists of up to 50 test cases. Each case starts with a positive integer n (n <= 1000) on the first line, which is the number of horses on each side. The next n integers on the second line are the speeds of Tian’s horses. Then the next n integers on the third line are the speeds of the king’s horses. The input ends with a line that has a single 0 after the last test case.
- 输出格式:For each input case, output a line containing a single number, which is the maximum money Tian Ji will get, in silver dollars.
- 样例输入:
- 3
- 92 83 71
- 95 87 74
- 2
- 20 20
- 20 20
- 2
- 20 19
- 22 18
- 0
- 样例输出:
- 200
- 0
- 0
示例代码:
#include <iostream>
#include <vector>
#include <cstdio>
#include <algorithm>
using namespace std;
vector<int> tianList;
vector<int> kingList;
void Init(vector<int> &list, int n){
int inputNum;
for(int i = 0; i < n; i++){
scanf("%d", &inputNum);
list.push_back(inputNum);
}
sort(list.begin(), list.end());
}
int main(){
int n;
while(cin >> n && n != 0){
tianList.clear();
kingList.clear();
Init(tianList, n);
Init(kingList, n);
int highT = n - 1, lowT = 0, highK = n - 1, lowK = 0;
int win = 0, lose = 0, equal = 0;
while(lowT <= highT){
while(lowT <= highT && tianList[lowT] > kingList[lowK]){
win++;
lowT++;
lowK++;
}
while(lowT <= highT && tianList[highT] > kingList[highK]){
win++;
highT--;
highK--;
}
if(lowT <= highT){
if(tianList[lowT] < kingList[highK]){
lose++;
}
lowT++;
highK--;
}
}
cout << (win - lose) * 200 << endl;
}
return 0;
}
5、题目描述:输入20个数,每个数都在1-10之间,求1-10中的众数(众数就是出现次数最多的数,如果存在一样多次数的众数,则输出权值较小的那一个)。【哈尔滨工业大学】
- 输入格式:测试数据有多组,每组输入20个1-10之间的数。
- 输出格式:对于每组输入,请输出1-10中的众数。
- 样例输入:
- 5 1 5 10 3 5 3 4 8 6 8 3 6 5 10 7 10 2 6 2
- 样例输出:
- 5
示例代码:
#include <iostream>
#include <cstring>
using namespace std;
int a[11];
int main(){
int inputNumber;
while(cin >> inputNumber){
memset(a, 0, sizeof(a));
a[inputNumber]++;
for(int i = 1; i <= 19; i++){
cin >> inputNumber;
a[inputNumber]++;
}
int mostCount = a[1], mostValue = 1;
for(int i = 2; i <= 10; i++){
if(a[i] > mostCount){
mostCount = a[i];
mostValue = i;
}
}
cout << mostValue << endl;
}
return 0;
}
6、题目描述:编写程序,读入一个整数N。若N为非负数,则计算N 到2N 之间的整数和;若N为一个负数,则求2N 到N 之间的整数和。【北京理工大学】
- 输入格式:第一行表示样例数m,接下来m行每行一个整数N,N的绝对值不超过100。
- 输出格式:输出m行,每行表示对应的题目所求。
- 样例输入:
- 2
- 2
- -1
- 样例输出:
- 9
- -3
示例代码:
#include <iostream>
#include <algorithm>
using namespace std;
int main(){
int caseNum, inputNum, result;
cin >> caseNum;
for(int i = 0; i < caseNum; i++){
cin >> inputNum;
result = 3 * abs(inputNum) * (abs(inputNum) + 1) / 2;
if(inputNum < 0){
result *= -1;
}
cout << result << endl;
}
return 0;
}
7、题目描述:求1-n内的完数,所谓的完数是这样的数,它的所有因子相加等于它自身,比如6有3个因子1,2,3,1+2+3=6,那么6是完数。即完数是等于其所有因子(除了它自己)相加和的数。【哈尔滨工业大学】
- 输入格式:测试数据有多组,输入n,n数据范围不大。
- 输出格式:对于每组输入,请输出1-n内所有的完数。如有案例输出有多个数字,用空格隔开,输出最后不要有多余的空格。
- 样例输入:
- 6
- 样例输出:
- 6
示例代码:
#include <iostream>
using namespace std;
int main(){
int n, sum;
while(cin >> n){
bool flag = false;
for(int i = 1; i <= n; i++){
sum = 0;
for(int j = 1; j <= i / 2; j++){
if(i % j == 0){
sum += j;
}
}
if(sum == i){
if(flag){
cout << " ";
}
flag = true;
cout << i;
}
}
}
return 0;
}
8、题目描述:给定三角形的三条边,a,b,c。判断该三角形类型。【哈尔滨工业大学】
- 输入格式:测试数据有多组,每组输入三角形的三条边。
- 输出格式:对于每组输入,输出直角三角形、锐角三角形、或是钝角三角形。
- 样例输入:
- 3 4 5
- 样例输出:
- 直角三角形
示例代码:
#include <iostream>
using namespace std;
int main(){
int edge1, edge2, edge3;
int min1, min2, maxValue, tmp;
while(cin >> edge1 >> edge2 >> edge3){
min1 = edge1, min2 = edge2, maxValue = edge3;
if(min1 > maxValue){
tmp = min1;
min1 = maxValue;
maxValue = tmp;
}
if(min2 > maxValue){
tmp = min2;
min2 = maxValue;
maxValue = tmp;
}
if(min1 * min1 + min2 * min2 == maxValue * maxValue){
cout << "直角三角形" << endl;
}else if(min1 * min1 + min2 * min2 > maxValue * maxValue){
cout << "锐角三角形" << endl;
}else{
cout << "钝角三角形" << endl;
}
}
return 0;
}
9、题目描述:输入一个英文句子,把句子中的单词(不区分大小写)按出现次数按从多到少把单词和次数在屏幕上输出来,要求能识别英文句号和逗号,即是说单词由空格、句号和逗号隔开。【北京理工大学】
- 输入格式:输入有若干行,总计不超过1000个字符。
- 输出格式:输出格式参见样例。
- 样例输入:
- A blockhouse is a small castle that has four openings through which to shoot.
- 样例输出:
- a:2
- blockhouse:1
- castle:1
- four:1
- has:1
- is:1
- openings:1
- shoot:1
- small:1
- that:1
- through:1
- to:1
- which:1
示例代码:(此题需要把注释的内容去掉,注释不去掉则只按字典序排序)
#include <string>
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
map<string, int> myMap;
vector<pair<string, int> > myList;
string getWord(string s, int &index){
string result = "";
while(index < s.size() && s[index] != ' ' && s[index] != '.' && s[index] != ','){
result += tolower(s[index]);
index++;
}
return result;
}
bool CompareDesc(const pair<string, int> p1, const pair<string, int> p2){
if(p1.second == p2.second){
return p1.first < p2.first;
}
return p1.second > p2.second;
}
int main(){
string s;
while(getline(cin ,s)){
myMap.clear();
myList.clear();
int i = 0;
while(i < s.size()){
if(s[i] != ' ' && s[i] != '.' && s[i] != ','){
myMap[getWord(s, i)]++;
}else{
i++;
}
}
for(map<string, int>::iterator iter = myMap.begin(); iter != myMap.end(); iter++){
//myList.push_back(make_pair(iter->first, iter->second));
cout << iter->first << ":" << iter->second << endl;
}
/*sort(myList.begin(), myList.end(), CompareDesc);
for(int i = 0; i < myList.size(); i++){
cout << myList[i].first << ":" << myList[i].second << endl;
}*/
}
return 0;
}
10、题目描述:北京大学对本科生的成绩施行平均学分绩点制(GPA)。既将学生的实际考分根据不同的学科的不同学分按一定的公式进行计算。 公式如下: 实际成绩 绩点 90——100 4.0 85——89 3.7 82——84 3.3 78——81 3.0 75——77 2.7 72——74 2.3 68——71 2.0 64——67 1.5 60——63 1.0 60以下 0 。1.一门课程的学分绩点=该课绩点*该课学分 2.总评绩点=所有学科绩点之和/所有课程学分之和 现要求你编写程序求出某人A的总评绩点(GPA)。【北京大学】
- 输入格式:第一行 总的课程数n(n<10);第二行 相应课程的学分(两个学分间用空格隔开);第三行 对应课程的实际得分;此处输入的所有数字均为整数。
- 输出格式:输出有一行,总评绩点,精确到小数点后2位小数。(printf("%.2f",GPA);)
- 样例输入:
- 5
- 4 3 4 2 3
- 91 88 72 69 56
- 样例输出:
- 2.52
示例代码:
#include <iostream>
#include <iomanip>
using namespace std;
const int MAX_N = 11;
int score[MAX_N];//成绩
int point[MAX_N];//学分
double GetCredit(int n){
if(n >= 90 && n <= 100){
return 4.0;
}else if(n >= 85 && n <= 89){
return 3.7;
}else if(n >= 82 && n <= 84){
return 3.3;
}else if(n >= 78 && n <= 81){
return 3.0;
}else if(n >= 75 && n <= 77){
return 2.7;
}else if(n >= 72 && n <= 74){
return 2.3;
}else if(n >= 68 && n <= 71){
return 2.0;
}else if(n >= 64 && n <= 67){
return 1.5;
}else if(n >= 60 && n <= 63){
return 1.0;
}else{
return 0.0;
}
}
int main(){
int n;
while(cin >> n){
int sumPoint = 0;
for(int i = 0; i < n; i++){
cin >> point[i];
sumPoint += point[i];
}
double sumCredit = 0.0;
for(int i = 0; i < n; i++){
cin >> score[i];
sumCredit += GetCredit(score[i]) * point[i];
}
cout << fixed << setprecision(2) << sumCredit / sumPoint << endl;
}
return 0;
}
11、题目描述:一个百万富翁遇到一个陌生人,陌生人找他谈了一个换钱的计划。该计划如下:我每天给你10 万元,你第一天给我1 分钱,第二天2 分钱,第三天4 分钱……这样交换 30 天后,百万富翁交出了多少钱?陌生人交出了多少钱?(注意一个是万元,一个是分)【哈尔滨工业大学】
- 输入格式:无
- 输出格式:输出两个整数,分别代表百万富翁交出的钱和陌生人交出的钱,富翁交出的钱以万元作单位,陌生人交出的钱以分作单位。
- 样例输入:无
- 样例输出:无
示例代码:
#include <iostream>
using namespace std;
int main(){
long long mill = 0;
long long stranger = 0;
long mul = 1;
for(int i = 0; i < 30; i++){
mill += 10;
stranger += mul;
mul *= 2;
}
cout << mill << " " << stranger << endl;
return 0;
}
12、题目描述:某程序员开始工作,年薪N万,他希望在中关村公馆买一套60平米的房子,现在价格是200万,假设房子价格以每年百分之K增长,并且该程序员未来年薪不变,且不吃不喝,不用交税,每年所得N万全都积攒起来,问第几年能够买下这套房子(第一年房价200万,收入N万)【北京大学】
- 输入格式:有多行,每行两个整数N(10<=N<=50), K(1<=K<=20)
- 输出格式:针对每组数据,如果在第21年或者之前就能买下这套房子,则输出一个整数M,表示最早需要在第M年能买下,否则输出Impossible,输出需要换行
- 样例输入:
- 50 10
- 40 10
- 40 8
- 样例输出:
- 8
- Impossible
- 10
示例代码:
#include <iostream>
using namespace std;
int main(){
int n, k;
while(cin >> n >> k){
int totalPay = n;
int currentPrice = 200;
int increase = currentPrice * k / 100;
int year = 1;
while(increase <= n && totalPay <= currentPrice){
year++;
totalPay += n;
currentPrice += increase;
increase = currentPrice * k / 100;
}
if(increase > n){
cout << "Impossible" << endl;
}else{
cout << year << endl;
}
}
return 0;
}
13、题目描述:给定两个字符串S1和S2,合并成一个新的字符串S。 合并规则为,S1的第一个字符为S的第一个字符,将S2的最后一个字符作为S的第二个字符; 将S1的第二个字符作为S的第三个字符,将S2的倒数第二个字符作为S的第四个字符,以此类推。【西北工业大学】
- 输入格式:包含多组测试数据,每组测试数据包含两行,代表长度相等的两个字符串S1和S2(仅由小写字母组成,长度不超过100)。
- 输出格式:合并后的新字符串S
- 样例输入:
- abc
- def
- 样例输出:
- afbecd
示例代码:
#include <iostream>
#include <string>
using namespace std;
int main(){
string s1, s2;
int len;
while(cin >> s1 >> s2){
len = s1.size();
for(int i = 0; i < len; i++){
cout << s1[i] << s2[len - 1 - i];
}
cout << endl;
}
return 0;
}
14、题目描述:编写程序,计算下列分段函数y=f(x)的值。当 0<= x <2,y= -x+2.5;当 2<= x <4,y=2-1.5(x-3)(x-3);当 4<= x <6,y=x/2-1.5;【北京理工大学】
- 输入格式:输入第一行为整数m表示样例数,接下来有m行每行一个整数x。
- 输出格式:输出m行分别表示对应的y值,保留小数点后一位小数。
- 样例输入:
- 2
- 1
- 3
- 样例输出:
- y=1.5
- y=2.0
示例代码:
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main(){
int caseNum, inputNum;
double result;
cin >> caseNum;
for(int i = 0; i < caseNum; i++){
cin >> inputNum;
if(0 <= inputNum && inputNum < 2){
result = -1.0 * inputNum + 2.5;
}else if(2 <= inputNum && inputNum < 4){
result = 2 - 1.5 * (inputNum - 3) * (inputNum - 3);
}else if(4 <= inputNum && inputNum < 6){
result = inputNum / 2.0 - 1.5;
}
cout<< fixed << setprecision(1) << "y=" << result << endl;
}
return 0;
}
15、题目描述:给定一个数组,它的第i 个元素是一支给定股票第 i 天的价格。如果你最多只允许完成一笔交易(即买入和卖出一支股票一次),设计一个算法来计算你所能获取的最大利润。注意:你不能在买入股票前卖出股票。【LeetCode 121】
示例 1:
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
示例 2:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
示例代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int len = prices.size();
if(len == 0){
return 0;
}
vector<int> dp(len);//dp[i]表示第i天卖的最大收益
int minValue = prices[0], result = 0;
dp[0] = 0;
for(int i = 1 ; i < prices.size(); i++){
dp[i] = max(dp[i - 1], prices[i] - minValue);
minValue = min(minValue, prices[i]);
result = max(result, dp[i]);
}
return result;
}
};
16、题目描述:给定一个整数数组,其中第i个元素代表了第i天的股票价格 。设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。【LeetCode 309】
示例:
输入: [1,2,3,0,2]
输出: 3
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]
示例代码:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int len = prices.size();
if(len == 0){
return 0;
}
vector<int> sell(len, 0);//sell[i]表示第i天卖的最大利润
vector<int> buy(len, 0);//buy[i]表示第i天买的最大利润
vector<int> cold(len, 0);//cold[i]表示第i天冷冻的最大利润
buy[0] = -prices[0];
for(int i = 1; i < len; i++){
sell[i] = max(buy[i - 1] + prices[i], sell[i - 1]);
buy[i] = max(cold[i - 1] - prices[i], buy[i - 1]);
cold[i] = max(sell[i - 1], cold[i - 1]);
}
return sell[len - 1];
}
};
17、题目描述:给定一个整数数组prices,其中第i个元素代表了第i天的股票价格 ;非负整数?fee 代表了交易股票的手续费用。你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。返回获得利润的最大值。注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。【LeetCode 714】
示例 1:
输入: prices = [1, 3, 2, 8, 4, 9], fee = 2
输出: 8
解释: 能够达到的最大利润: 在此处买入 prices[0] = 1,在此处卖出 prices[3] = 8,在此处买入 prices[4] = 4,在此处卖出 prices[5] = 9,总利润:((8 - 1) - 2) + ((9 - 4) - 2) = 8.
注意:
0 < prices.length <= 50000.
0 < prices[i] < 50000.
0 <= fee < 50000.
示例代码:
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int len = prices.size();
if(len == 0){
return 0;
}
vector<int> sell(len, 0);//sell[i]表示第i天卖出可以获得的最大利润
vector<int> buy(len, 0); //buy[i]表示第i天买入可以获得的最大利润
buy[0] = -prices[0];
for(int i = 1; i < len; i++){
sell[i] = max(sell[i - 1], buy[i - 1] + prices[i] - fee);
buy[i] = max(buy[i - 1], sell[i - 1] - prices[i]);
}
return sell[len - 1];
}
};
18、题目描述:(这是一个 交互式问题)给你一个 山脉数组mountainArr,请你返回能够使得mountainArr.get(index)等于target最小的下标 index值。如果不存在这样的下标 index,就请返回-1。何为山脉数组,如果数组A 是一个山脉数组的话,那它满足如下条件:
首先,A.length >= 3。其次,在0 < i< A.length - 1条件下,存在 i 使得:A[0] < A[1] < ... A[i-1] < A[i],A[i] > A[i+1] > ... > A[A.length - 1],你将不能直接访问该山脉数组,必须通过MountainArray接口来获取数据:MountainArray.get(k)- 会返回数组中索引为k的元素(下标从 0 开始),MountainArray.length()- 会返回该数组的长度。【LeetCode 1095】
示例 1:
输入:array = [1,2,3,4,5,3,1], target = 3
输出:2
解释:3 在数组中出现了两次,下标分别为 2 和 5,我们返回最小的下标 2。
示例 2:
输入:array = [0,1,2,4,2,1], target = 3
输出:-1
解释:3 在数组中没有出现,返回 -1。
提示:
3 <= mountain_arr.length() <= 10000
0 <= target <= 10^9
0 <= mountain_arr.get(index) <=10^9
示例代码:
/**
* // This is the MountainArray's API interface.
* // You should not implement it, or speculate about its implementation
* class MountainArray {
* public:
* int get(int index);
* int length();
* };
*/
class Solution {
public:
map<int, int> myMap; //查找过的元素存放在map当中,防止多次进行get操作
//二分查找
int Help(int target, MountainArray &mountainArr, int low, int high, int style){
if(low > high){
return -1;
}
int mid = (low + high) / 2, value;
if(myMap.find(mid) != myMap.end()){
value = myMap[mid];
}else{
value = mountainArr.get(mid);
myMap.insert(pair<int, int>(mid, value));
}
if(value == target){
return mid;
}
//style为1,则处理左边递增列表遍历
if(style == 1){
if(value < target){
return Help(target, mountainArr, mid + 1, high, style);
}else{
return Help(target, mountainArr, low, mid - 1, style);
}
}
//否则处理右边递减列表遍历
else{
if(value < target){
return Help(target, mountainArr, low, mid -1, style);
}else{
return Help(target, mountainArr, mid + 1, high, style);
}
}
}
int findInMountainArray(int target, MountainArray &mountainArr) {
myMap.clear();
int length = mountainArr.length();
//找山顶,循环遍历后山顶为mid
int low = 0, high = length - 1, mid;
while(low < high){
mid = (low + high) / 2;
int val = mountainArr.get(mid);
myMap.insert(pair<int, int>(mid, val));
int leftVal = mountainArr.get(mid - 1);
myMap.insert(pair<int, int>(mid - 1, leftVal));
int rightVal = mountainArr.get(mid + 1);
myMap.insert(pair<int, int>(mid + 1, rightVal));
if(leftVal < val && rightVal < val){
break;
}else if(leftVal < val && rightVal > val){
low = mid;
}else{
high = mid;
}
}
if(myMap[mid] == target){
return mid;
}
int left = Help(target, mountainArr, 0, mid - 1, 1);
if(left == -1){
return Help(target, mountainArr, mid + 1, length - 1, 2);
}else{
return left;
}
}
};
19、题目描述:首先输入一个5 * 5的数组,然后输入一行,这一行有四个数,前两个代表操作类型,后两个数x y代表需操作数据为以x y为左上角的那几个数据。 操作类型有四种: 1 2 表示:90度,顺时针,翻转4个数 1 3 表示:90度,顺时针,翻转9个数 2 2 表示:90度,逆时针,翻转4个数 2 3 表示:90度,逆时针,翻转9个数【北京邮电大学】
- 输入格式:输入有多组数据。每组输入一个5 * 5的数组,然后输入一行,这一行有四个数,前两个代表操作类型,后两个数x y代表需操作数据为以x y为左上角的那几个数据。
- 输出格式:输出翻转后的数组。
- 样例输入:
- 1 2 3 4 5
- 6 7 8 9 10
- 11 12 13 14 15
- 16 17 18 19 20
- 21 22 23 24 25
- 1 3 1 1
- 样例输出:
- 11 6 1 4 5
- 12 7 2 9 10
- 13 8 3 14 15
- 16 17 18 19 20
- 21 22 23 24 25
示例代码:
#include <iostream>
using namespace std;
int a[5][5];
void Reverse(int oper, int num, int x, int y){
if(oper == 1){//顺时针
//交换副对角线两侧的对称元素
for(int i = 0; i < num; i++){
for(int j = 0; j < num - i; j++){
swap(a[i + x][j + y], a[x + num - 1 - j][y + num - 1 - i]);
}
}
}else{//逆时针
//交换主对角线两侧的对称元素
for(int i = 0; i < num; i++){
for(int j = i + 1; j < num; j++){
swap(a[i + x][j + y], a[j + x][i + y]);
}
}
}
//交换第i行和第n-1-i行
for(int i = 0; i < num / 2; i++){
for(int j = y; j < y + num; j++){
swap(a[i + x][j], a[x + num - 1 - i][j]);
}
}
}
int main(){
int oper1, oper2, x, y;
while(cin >> a[0][0]){
for(int i = 1; i < 5; i++){
cin >> a[0][i];
}
for(int i = 1; i < 5; i++){
for(int j = 0; j < 5; j++){
cin >> a[i][j];
}
}
cin >> oper1 >> oper2 >> x >> y;
if(oper1 == 1){ //顺时针90度
if(oper2 == 2){ //翻转4个数
Reverse(1, 2, x - 1, y - 1);
}else{ //翻转9个数
Reverse(1, 3, x - 1, y - 1);
}
}else{ //逆时针90度
if(oper2 == 2){//翻转4个数
Reverse(2, 2, x - 1, y - 1);
}else{ //翻转9个数
Reverse(2, 3, x - 1, y - 1);
}
}
bool flag;
for(int i = 0; i < 5; i++){
flag = false;
for(int j = 0; j < 5; j++){
if(flag){
cout << " ";
}
flag = true;
cout << a[i][j];
}
cout << endl;
}
}
return 0;
}
附注:
(1)逆时针90度,第一步交换主对角线两侧的对称元素,第二步交换第i行和第n-1-i行,即得到结果。 顺时针90度, 第一步交换副对角线两侧的对称元素,第二步交换第i行和第n-1-i行,即得到结果。
20、题目描述:请编写一个程序,从键盘上输入n(n 的范围是1~20),求n 的阶乘。【北京理工大学】
- 输入格式:输入第一行为样例数m,接下来m行每行一个整数n,n不超过20。
- 输出格式:输出m行表示对应的n的阶乘。
- 样例输入:
- 1
- 3
- 样例输出:
- 6
示例代码:
#include <iostream>
using namespace std;
long long arr[21];
int main(){
int caseNum, n;
arr[0] = 1;
for(int i = 1; i <= 20; i++){
arr[i] = arr[i - 1] * i;
}
cin >> caseNum;
for(int i = 0; i < caseNum; i++){
cin >> n;
cout << arr[n] << endl;
}
return 0;
}