牛客寒假算法基礎集訓營6
文章目錄
A 配對
現在有正整數集合 A 和 B,每個集合裏有 N 個數,你要建立他們間的一一映射,將每對配對的數字相加可以得到 N 個和,你要做的就是最大化第 K 大的和。
分別將前k大的數, 一個集合第i小的和另一個集合第i大的, 配對, 得出k個數最後最小的那個數就是答案。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const long long mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const double PI = 3.141592;
const int e = 1e5 + 5;
int a[e], b[e], n, k, ans = INF;
int main()
{
cin >> n >> k;
for(int i = 1; i <= n; i++)
cin >> a[i];
for(int i = 1; i <= n; i++)
cin >> b[i];
sort(a + 1, a + n + 1);
sort(b + 1, b + n + 1);
for(int i = n; i > n - k; i--)
ans = min(ans, a[i] + b[n - k + n + 1 - i]);
printf("%d\n", ans);
return 0;
}
F 十字陣列
小 Q 新學會了一種魔法,可以對一個 N行M列 的網格上的敵人造成傷害 , 第 i 次使用魔法可以對網格上的一個十字形區域(即第 xi 行和第 yi 列的並)中的每個格子上的敵人造成 zi 點傷害 , 現在小 Q 一共使用了 H 次魔法,輸出Σwij(i+j)對 10^9+7 取模的結果。
思路:開額外兩個數組分別記錄第i行受到的總傷害,和第j列受到的總傷害,mp來記錄第i行,第j列的單位受到的傷害。。直接將全部點受到的傷害存入mp會超時。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const long long mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const double PI = 3.141592;
const int e = 1e5 + 5;
ll n, m, h, ans = 0;
ll a[2005], b[2005], mp[2005][2005];
int main()
{
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(mp, 0, sizeof(mp));
scanf("%lld%lld%lld", &n, &m, &h);
for(int i = 1; i <= h; i++){
ll x, y, z;
scanf("%lld%lld%lld", &x, &y, &z);
a[x] += z;
b[y] += z;
mp[x][y] += z;
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
ans = (ans + (ll)(a[i] + b[j] - mp[i][j]) * (i + j) % mod) % mod;
}
}
printf("%lld\n", ans);
return 0;
}
G 括號序列
合法括號序列的定義是:
1.空序列是合法括號序列
2.如果 S 是一個合法括號序列,那麼(S)是合法括號序列
3.如果 A 和 B 都是合法括號序列,那麼 AB 是一個合法括號序列
現在給定一個括號序列,求最少刪去幾個括號能得到一個合法的括號序列
思路:遍歷字符串,如果爲“(”,計數器+1
如果爲“)”且計數器大於0,計數器-1
如果爲“)”且計數器小於0,說明前面沒有與之對應的“(”,ans+1。
最後計數器中的值爲,爲匹配的“(”。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const long long mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const double PI = 3.141592;
const int e = 1e5 + 5;
int main()
{
int t;
cin >> t;
while(t--){
int n;
cin >> n;
string s;
cin >> s;
int sum = 0, ans = 0;//sum爲未匹配的(,ans爲未匹配的)
for(int i = 0; i < n; i++){
if(s[i] == '(') sum++;
else if(sum > 0) sum--;
else ans++;
}
cout << ans + sum << endl;//未匹配的(和未匹配的)相加
}
return 0;
}
J 簽到題
現有一個邊長爲正整數的三角形,問能否以其三個頂點爲圓心畫三個圓,使三個圓兩兩外切
A=r1+r2
B=r1+r3
C=r2+r3
三個方程三個未知量,有解,不存在“No”的情況。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const long long mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const double PI = 3.141592;
int main()
{
double a[5];
cin >> a[0] >> a[1] >> a[2];
sort(a, a + 3);
if(a[0] + a[1] <= a[2]) cout << "wtnl" << endl;
else{
double r[5];
r[3] = (a[2] - a[0] + a[1]) / 2;
r[1] = a[1] - r[3];
r[2] = a[2] - r[3];
sort(r + 1, r + 4);
cout << "Yes" << endl;
printf("%.2f %.2f %.2f\n", r[1], r[2], r[3]);
}
return 0;
}