機試編程(九)

機試編程(九)

目錄:

  1. 應用實例
    1. 奇偶校驗【華中科技大學】
    2. 互換最大最小數【哈爾濱工業大學】
    3. 查找【北京郵電大學】
    4. 田忌賽馬 Tian Ji -- The Horse Racing【hdu 1052】
    5. 衆數【哈爾濱工業大學】
    6. 整數和【北京理工大學】
    7. 完數【哈爾濱工業大學】
    8. 判斷三角形類型【哈爾濱工業大學】
    9. 單詞識別【北京理工大學】
    10. 學分績點【北京大學】
    11. 百萬富翁【哈爾濱工業大學】
    12. 買房子【北京大學】
    13. 合併符串【西北工業大學】
    14. 分段函數【北京理工大學】
    15. 買賣股票【LeetCode 121】
    16. 最佳買賣股票時機含冷凍期【LeetCode 309】
    17. 買賣股票的最佳時機含手續費【LeetCode 714】
    18. 山脈數組中查找目標值【LeetCode 1095】
    19. C翻轉【北京郵電大學】
    20. 階乘【北京理工大學】

一、應用實例:

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章