洛谷基础赛9
A
清除的代价一样,贪心选择好处最多的清除
int n, m, k, t, x, tmp, s = 0;
int a[1000010];
void solve(){
cin >> n >> m >> k >> t;
for(int i = 1; i <= n * m; i ++){
cin >> a[i];
}
sort(a + 1, a + n * m + 1);
for(int i = n * m; i >= 1; i --){
if(t){
t --;
tmp += a[i];
t += tmp / k;
tmp %= k;
s += a[i];
}
else{
break;
}
}
cout << s << '\n';
}
B
#include<bits/stdc++.h>
using namespace std;
#define int long long
int const P = 998244353;
void solve(){
int n;
cin >> n;
auto ksm = [](int &&a, int k, const int &P){
int res = 1;
while(k){
if(k & 1){
res = (res * a) % P;
}
k >>= 1;
a = (a * a) % P;
}
return res;
};
int res = ksm(26LL, n, P) - 2LL * ksm(25LL, n, P) + ksm(24LL, n, P);
cout << (res % P + P) % P << '\n';
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
cin >> T;
while (T --){
solve();
}
return 0;
}
/*
由 'a' ~ 'z' 构成, 26 ^ n 方案
不包含 'a', 25 ^ n
不包含 'b', 25 ^ n
不包含 'a' 和 'b', 24 ^ n
答案 = 所有构造方式 - 不包含 'a' - 不包含 'b' + 不包含 'a' 和 'b'
*/
C
初始情况为 n = 1 , m = 1 n=1,m=1 n=1,m=1 时, 输出 − 1 -1 −1
其余情况,用 f i , j f_{i,j} fi,j 表示现在正在操作的选手走到 i i i 行 j j j 列的获胜几率,
f 1 , 1 = 1 f_{1,1}=1 f1,1=1 ; f 1 , 2 = 1 f_{1,2}=1 f1,2=1 ; f 2 , 1 = 1 f_{2,1}=1 f2,1=1 ; . . . . . ..... .....
总之是可以线性递推的
#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve(){
// n 减少,上
// m 减少,右
int n, m;
cin >> n >> m;
swap(n, m);
if(n + m == 2){
cout << "-1\n";
}
else if((n + m) % 2 == 1){
// 全 1
int dis = n - 1;
if(dis & 1){
cout << "1\n"; // 令 n 减小
}
else{ // 令 m 减小
cout << "2\n";
}
}
else{ // 0 1 0 1 0
// first coordinate : {1, n + m - 1}
int dis = n - 1;
if(dis & 1){
cout << "3\n";
}
else{
cout << "-1\n";
}
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
cin >> T;
while (T --){
solve();
}
return 0;
}
D
这题时限纯纯有病,不开快速读 O ( n ) O(n) O(n) 预处理个前缀和都超时
题目让求 ∑ 2 ∣ x − a i ∣ + p × x \sum2|x-a_i|+p\times x ∑2∣x−ai∣+p×x 尽可能小时 x x x 可取的最小值, x ∈ Z x\in Z x∈Z
首先把单调的情况去掉,剩下的就一定是一个有极值点的函数
答案在极值点周围 + 两个端点处取得
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n, p;
int a[1000010], s[1000010];
inline int read(){
int x = 0, f = 1; // f 代表正负
char c = getchar();
while(c < '0' || c > '9'){
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9'){
x = x * 10LL + c - '0';
c = getchar();
}
return x * f;
}
int ask(int l, int r){
return s[r] - s[l - 1];
}
int cost(int pos){
int x = a[pos];
int res = (pos - 1) * x - ask(1, pos - 1);;
res += ask(pos, n) - (n - pos + 1) * x;
res = res * 2 + p * x;
return res;
}
void solve(){
cin >> n >> p;
for(int i = 1; i <= n; i ++){
a[i] = read();
}
sort(a + 1, a + n + 1);
for(int i = 1; i <= n; i ++){
s[i] = s[i - 1] + a[i];
}
if(p > 2 * n || p < - 2 * n){
cout << "No\n";
return ;
}
int pos = (n * 2 - p) / 4;
pair<int, int> res = {2e18, -1};
for(int i = max(pos - 2, 1LL); i <= min(pos + 2, n); i ++){
int tmp = cost(i);
if(tmp < res.first){
res.first = tmp;
res.second = i;
}
}
int tmp = cost(1);
if(tmp <= res.first){
res.first = tmp;
res.second = 1;
}
tmp = cost(n);
if(tmp < res.first){
res.first = tmp;
res.second = n;
}
cout << a[res.second] << '\n';
}
signed main(){
int T;
cin >> T;
while (T --){
solve();
}
return 0;
}