訓練情況
賽後反思
A題最簡單的題愣神了,浪費了幾分鐘,其他方面正常表現
A題
相鄰的兩個差絕對值不能出現除了 \(5\) 和 \(7\) 以外的,直接模擬即可。
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve(){
int n; cin>>n;
vector<int> a(n + 1);
for(int i = 1;i<=n;i++) cin>>a[i];
bool flag = true;
for(int i = 2;i<=n;i++){
int x = abs(a[i] - a[i-1]);
if(x != 5 && x != 7) flag = false;
}
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
signed main(){
int T; cin>>T; while(T--)
solve();
return 0;
}
B題
有 \(n\) 個貨架,\(k\) 件商品,每個貨架只擺同一種品牌的商品,所以我們統計每個品牌商品的價格和,最後取出價格和最大的前 \(n\) 個品牌的商品即可,使用優先佇列維護。
#include <bits/stdc++.h>
#define int long long
using namespace std;
struct node{
int a,b;
};
bool cmp(node x,node y){
return x.a < y.a;
}
void solve(){
int n,k; cin>>n>>k;
priority_queue<int> q;
vector<node> a(k + 1);
for(int i = 1;i<=k;i++){
cin>>a[i].a>>a[i].b;
}
sort(a.begin() + 1,a.end(),cmp);
int sum = a[1].b;
for(int i = 2;i<=k;i++){
if(a[i].a == a[i-1].a) sum += a[i].b;
else q.push(sum),sum=a[i].b;
}
q.push(sum);
int ans = 0;
for(int i = 1;i<=n;i++){
if(!q.size()) break;
ans += q.top();
q.pop();
}
cout<<ans<<endl;
}
signed main(){
int T; cin>>T; while(T--)
solve();
return 0;
}
C題
我們發現修改某一位只會對附近相鄰四位產生貢獻,只會有下面幾種情況
110X
?11X0
??1X00
???X100
所以我們在替換某一位的時候,先把替換位置附近的這幾種情況記錄的 1100 子串位置和個數先全部去掉,再統計。此時我們只需要維護整個字串中子串 1100 的個數即可。
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve(){
string s; cin>>s;
int n = s.size();
vector<bool> vis(n);
int cnt = 0;
for(int i = 0;i<n-3;i++){
if(s.substr(i,4) == "1100") vis[i] = 1,cnt++;
}
int k; cin>>k;
while(k--){
int pos,v; cin>>pos>>v;
s[pos-1] = v+'0';
for(int i = max(0ll,pos-4);i<=min(n-1,pos-1);i++){
if(vis[i]) vis[i] = 0,cnt--;
}
for(int i = max(0ll,pos-4);i<=min(n-1,pos-1);i++){
if(s.substr(i,4) == "1100") vis[i] = 1,cnt++;
}
if(cnt) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
signed main(){
int T; cin>>T; while(T--)
solve();
return 0;
}
D題
主要難點是繞順時針,而且從外往裡,一共會有 \(\lfloor \frac{min(n,m)}{2} \rfloor\) 圈,迴圈挺難寫的,我們分成順時針四段四條邊寫即可,注意一下統計出現次數,首位相接也算。
#include <bits/stdc++.h>
#define int long long
using namespace std;
int pd(string s){
int cnt = 0;
int n = s.size();
for(int i = 0;i<n-3;i++){
if(s.substr(i,4) == "1543") cnt++;
}
if(s[n-3] == '1' && s[n-2] == '5' && s[n-1] == '4' && s[0] == '3') cnt++;
if(s[n-2] == '1' && s[n-1] == '5' && s[0] == '4' && s[1] == '3') cnt++;
if(s[n-1] == '1' && s[0] == '5' && s[1] == '4' && s[2] == '3') cnt++;
return cnt;
}
void solve(){
int n,m; cin>>n>>m;
vector<string> s(n);
vector<vector<bool>> vis(n+1,vector<bool>(m+1));
for(int i = 0;i<n;i++) cin>>s[i];
string t;
int ans = 0;
for(int i = 0;i<min(n,m)/2;i++){
t = "";
for(int j = i;j<=m-1-i;j++) t+=s[i][j];
for(int j = i+1;j<=n-1-i;j++) t+=s[j][m-i-1];
for(int j = m-1-i-1;j>=i;j--) t+=s[n-i-1][j];
for(int j = n-1-i-1;j>=i+1;j--) t+=s[j][i];
// cout<<t<<endl;
ans += pd(t);
}
cout<<ans<<endl;
}
signed main(){
int T; cin>>T; while(T--)
solve();
return 0;
}