The 19th Heilongjiang Provincial Collegiate Programming Contest
B. String
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
using vi = vector<int>;
i32 main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
string s;
cin >> s;
vector<char> t;
for(auto c : s){
t.push_back(c);
if(t.size() >= 3){
if(t[t.size() - 1] == t[t.size() - 2] and t[t.size() - 1] == t[t.size() - 3])
t.pop_back(),t.pop_back(),t.pop_back();
}
}
if(t.empty()) cout << "NAN\n";
else {
for(auto c : t)
cout << c;
cout << "\n";
}
return 0;
}
D. Card Game
贪心题,尽可能的给对方造成高的伤害。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
void solve(){
int n,hpa,hpb;
cin >> n >> hpa >> hpb;
vector<int> a(n),b(n);
for (int i = 0;i < n;i++){
cin >> a[i];
}
for (int i = 0;i < n;i++){
cin >> b[i];
}
sort(a.begin(),a.end(),greater<>());
sort(b.begin(),b.end(),[](int x,int y){
if (x != -1 && y != -1){
return x < y;
}else{
return (x == -1) < (y == -1);
}
});
for (int i = 0;i < n && hpa > 0 && hpb > 0;i++){
if (a[i] == -1 || b[i] == -1) continue;
hpa -= b[i];
hpb -= a[i];
}
if(hpb <= 0 and hpa > 0) cout << "yes\n";
else cout << "no\n";
return;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--){
solve();
}
return 0;
}
F. Photography
首先在枚举中间的三个点,然后贪心的选择首尾两个点。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int inf = 1e9;
const int N = 5e3 + 7;
int n,m,a[N],d[N][6],vis[N],ans = 0;
vector<int> e[N];
using pii = pair<int,int>;
void dfs(int fa,int u,int t,int res){
if (t > 5) return;
d[fa][t] = max(d[fa][t],res);
ans = max(d[fa][t],ans);
for (auto v : e[u]){
if (vis[v]) continue;
vis[v] = 1;
dfs(fa,v,t + 1,res + a[v]);
vis[v] = 0;
}
}
int main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
cin >> n >> m;
for (int i = 1;i <= n;i++){
cin >> a[i];
}
for (int i = 1;i <= m;i++){
int u,v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
vector<array<int,3>> edge;
for(int i = 1; i <= n; i ++){
for(int x = 0; x < e[i].size(); x ++){
for(int y = 0; y < x; y ++ ){
edge.push_back({e[i][x], i , e[i][y]});
}
}
}
if(edge.empty()) {
for (int i = 1;i <= n;i++){
vis[i] = 1;
dfs(i,i,1,a[i]);
vis[i] = 0;
}
cout << ans << "\n";
return 0;
}
vector<set<pii>> cnt(n + 1);
for(int x = 1; x <= n; x ++){
for(const auto y : e[x]){
cnt[x].emplace(-a[y], y);
if(cnt[x].size() > 5)
cnt[x].erase(prev(cnt[x].end()));
}
}
for(const auto &[x,y,z] : edge){
set<int> p;
p.insert(x);
p.insert(y);
p.insert(z);
for(auto [_ , i] : cnt[x]){
if(p.count(i)) continue;
p.insert(i);
break;
}
for(auto [_ , i] : cnt[z]){
if(p.count(i)) continue;
p.insert(i);
break;
}
int cur = 0;
for(auto i : p)
cur += a[i];
ans = max(ans, cur);
}
cout << ans << "\n";
return 0;
}
G. Grey-like Code
打表找规律,发现答案是\(2^{2^{n-1} - n}\)
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
using vi = vector<int>;
#define int i64
const int mod = 998244353;
int power(int x, int y , int p = mod) {
int ans = 1;
while(y) {
if(y & 1) ans = ans * x % p;
x = x * x % p , y /= 2;
}
return ans;
}
i32 main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
int n;
cin >> n;
int phi = mod - 1;
int x = (power(2 , n - 1 , phi) - n + phi) % phi;
cout << power(2 , x);
return 0;
}
I. This is an easy problem
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
using vi = vector<int>;
#define lowbit(x) (x & -x)
i32 main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
int x , res = 0;
cin >> x;
while(x)
x -= lowbit(x), res ++;
cout << res << "\n";
return 0;
}
J. Trade
动态规划,记\(f[i][j]\)表示从\((1,1)\)到\((i,j)\)只经过合法路径所需要的最短距离。
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
#define int i64
using vi = vector<int>;
const int inf = 1e18;
i32 main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int n, m;
cin >> n >> m;
vector a(n + 1, vi(m + 1)), b(n + 1, vi(m + 1));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> b[i][j];
vector f(n + 1, vi(m + 1, inf));
for (int i = 1, g; i <= n; i++)
for (int j = 1; j <= m; j++) {
if (i == 1 and j == 1) f[1][1] = b[1][1];
else {
g = min(f[i - 1][j], f[i][j - 1]) + b[i][j];
if (g + a[1][1] <= a[i][j]) f[i][j] = g;
}
}
for (int i = 1; i <= m; i++)
if (f[n][i] != inf) {
cout << "YES\n";
return 0;
}
for (int i = 1; i <= n; i++)
if (f[i][m] != inf) {
cout << "YES\n";
return 0;
}
cout << "NO\n";
return 0;
}
K. Puzzle
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
using vi = vector<int>;
#define lowbit(x) (x & -x)
i32 main(){
ios::sync_with_stdio(false), cin.tie(nullptr);
vi a(4);
for(auto & i : a) cin >> i;
sort(a.begin(), a.end());
set<int> cnt;
do{
cnt.insert(a[0]+a[1]+a[2]+a[3]);
cnt.insert(a[0]+a[1]+a[2]-a[3]);
cnt.insert(a[0]+a[1]+a[2]*a[3]);
cnt.insert(a[0]+a[1]-a[2]+a[3]);
cnt.insert(a[0]+a[1]-a[2]-a[3]);
cnt.insert(a[0]+a[1]-a[2]*a[3]);
cnt.insert(a[0]+a[1]*a[2]+a[3]);
cnt.insert(a[0]+a[1]*a[2]-a[3]);
cnt.insert(a[0]+a[1]*a[2]*a[3]);
cnt.insert(a[0]-a[1]+a[2]+a[3]);
cnt.insert(a[0]-a[1]+a[2]-a[3]);
cnt.insert(a[0]-a[1]+a[2]*a[3]);
cnt.insert(a[0]-a[1]-a[2]+a[3]);
cnt.insert(a[0]-a[1]-a[2]-a[3]);
cnt.insert(a[0]-a[1]-a[2]*a[3]);
cnt.insert(a[0]-a[1]*a[2]+a[3]);
cnt.insert(a[0]-a[1]*a[2]-a[3]);
cnt.insert(a[0]-a[1]*a[2]*a[3]);
cnt.insert(a[0]*a[1]+a[2]+a[3]);
cnt.insert(a[0]*a[1]+a[2]-a[3]);
cnt.insert(a[0]*a[1]+a[2]*a[3]);
cnt.insert(a[0]*a[1]-a[2]+a[3]);
cnt.insert(a[0]*a[1]-a[2]-a[3]);
cnt.insert(a[0]*a[1]-a[2]*a[3]);
cnt.insert(a[0]*a[1]*a[2]+a[3]);
cnt.insert(a[0]*a[1]*a[2]-a[3]);
cnt.insert(a[0]*a[1]*a[2]*a[3]);
}while(next_permutation(a.begin(), a.end()));
cout << cnt.size() << "\n";
return 0;
}