1.扎銀花
兩組數據比大小,取出最大的三個數比較他們的和,輸出和更大的那個數,如果一樣,也輸出。
- 使用內置的sort比手寫bubblesort只取前三個更快?
2.最長上升子串構造
從序列中刪除一個數,求所有的刪除方案中,最長上升子串(連續的)的長度。
#include"pch.h"
#include <iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> num(n);
vector<int> len(n);//以當前節點爲首,最長連續遞增子序列長度
vector<int> start(n);//當前節點爲尾,最長連續遞增子序列的首位置
len[n - 1] = 1;
start[0] = 0;
int maxx = 0;
for (int i = 1; i < n; i++) {
if (num[i] < num[i - 1]) start[i] = start[i - 1];
else start[i] = i;
}
for (int i = n - 2; i >= 0; i--) {
if (num[i] < num[i + 1]) {
len[i] = len[i - 1] + 1;
maxx = max(len[i], maxx);
}
else len[i] = 1;
}
int res = 0;
for (int i = 1; i < n; i++) {
if (num[i - 1] < num[i + 1]) {
int tmp = len[i + 1] + start[i-1] - i;
maxx = max(tmp, maxx);
}
}
cout << maxx;
return 0;
}
3.做任務
n個任務,對於每個任務都有k個子任務,每個子任務花費的時間與父任務無關,只與出現順序有關,每個父任務、子任務都只能完成一次,完成一個子任務會給p分,完成一個任務的k個子任務後,會得到額外的q分,求m時間內,最大得分。
#include"pch.h"
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
/*3.n個任務,對於每個任務都有k個子任務,
每個子任務花費的時間與父任務無關,
只與出現順序有關,每個父任務、子任務都只能完成一次,
完成一個子任務會給p分,完成一個任務的k個子任務後,
會得到額外的q分,求m時間內,最大得分*/
int main() {
int n, k, m, p, q;
cin >> n >> k >> m >> p >> q;
vector<int> jobs(k);//k個子任務
long res = 0;
long sum = 0;//單個任務總時長
for (int i = 0; i < k; i++) {
cin >> jobs[i];
sum += jobs[i];//統計一個父任務的總時長
}
sort(jobs.begin(), jobs.end());
int l = (int)(m / sum);//最多能完成幾個父任務
if (n < l) l = n;
for (int i = 0; i <= l; i++) {
long time = m - sum * i;//完成i個父任務後還剩多少時間
long score = i * (p*k + q);//完成i個父任務的總分
int remain = n - i;//剩下多少個父任務沒有完成
for (int j = 0; j < k; j++) {//嘗試完成子任務
if (jobs[j] * remain > time) {
//剩餘時間t < 完成剩餘父任務的第j個子任務
score += ((time / jobs[j])*p);
//得得分數+剩餘時間能夠完成的第j個子任務的個數
break;
}
else {
time -= jobs[j] * remain;
//剩餘時間夠的話,就減去完成剩餘父任務所有j子任務的時間
score += p * remain;
}
}
if (score > res) res = score;
}
cout << res;
return 0;
}
4. 跑步
準備正好跑k距離,城市道路可以看成n個點,m條無向邊組成的無向圖,每邊由固定的長度。
跑步前往一個目的地時一定要走最短距離,如果正好跑k距離,能夠到達的目的地的個數,目的地可能在圖的點上,也可能在邊上,且該目的地距離他起點的最短路徑正好k距離。
若k大於所有路徑之和,自然沒有這樣的目的地,返回0。
示例:點數,邊數,起點編號,m行無向邊:u->v,w長度,下一行:k
3 3 1
1 2 2
2 3 3
1 3 4
4
輸出:2,目的地是編號3的點,以及在2->3路徑2/3處的一個點。
#include"pch.h"
#include <iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
const int maxn = 1000;
const int INF = 1000000;
int n, m, k;
int d[maxn], w[maxn][maxn],g[maxn][maxn];
int vis[maxn] = { 0 };
void dijkstra(int s) {
fill(d, d + maxn, INF);
d[s] = 0;
int i, j, v;
for (i = 0; i < n; i++) {
int u = -1;
int min = INF;
for (j = 0; j < n; j++) {
if (vis[j] == 0 && d[j] < min) {
u = j; min = d[j];
}
}
if (u == -1) return;
vis[u] = 1;
for (v = 0; v < n;v++) {
if (vis[v] == 0 && g[u][v]!=INF) {
if (d[v] > d[u] + g[u][v]) {
d[v] = d[u] + g[u][v];
}
}
}
}
}
int main() {
int s;
cin >> n >> m >> s;
fill(g[0], g[0] + maxn * maxn, INF);
for (int i = 0; i < n; i++) {
int a, b, c;
cin >> a >> b >> c;
g[a-1][b-1] = c;
g[b-1][a-1] = c;
}
cin >> k;
dijkstra(s-1);
int res = 0;
for (int i = 0; i < n; i++) {
if (d[i] == k) res++;//cout << d[i] << " ";
}//s到每個點的最短距離
//再求,到各個邊上點的情況
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (g[i][j] == INF) continue;
if (d[i]<k && d[i] + g[i][j]>k) {
int tmp = d[i] + g[i][j] - k;
if (d[j] + tmp >= k) res++;
}
}
}
cout << res;
return 0;
}
- 不知道對不對
- 利用dijkstra,先求起點到其餘各點的最短距離
- 再求在邊上的情況,u-v這條邊,dis[u]<k && dis[u]+g[u][v]>k,且從u到達比從v到達這個點要近,就是說這個邊上的這個點,最短距離是從u來的,也算是一種情況
5.序列最長不下降子序列
1,0,0,1,1的最長不下降子序列是0,0,1,1
某序列只有1和0,完成(1)某段區間的0變成1,(2)求整段序列的最長不下降子序列長度,每組操作後都會對序列造成改變,就是說整個序列會不停變化。
輸入:n,m,序列長度和查詢次數 (n:[1,100000],m:[1,100000],x,y:[1,n])
n行無空格的數字,只有0或1
m行個詢問,兩個操作的詢問方式:(1)c x y 將區間[x,y]的0變爲1,1變爲0(2)q 詢問整段序列的最長不下降子序列長度。(整個序列下標:1,2,3,...,n)
輸出:對於q類詢問,輸出最長不下降自序列長度
示例:
5 5
10011
q 長度:4
c 1 5 修改後變成:01100
q 長度:3
c 1 3 修改後變成:10000
q 長度:4
輸出:4 3 4