Codeforces Round 933 (Div. 3)
A
暴力
查看代码
void solve() {
int n,m,k;
cin>>n>>m>>k;
vector<int>b(n),c(m);
for(int i=0;i<n;++i)cin>>b[i];
for(int i=0;i<m;++i)cin>>c[i];
int ans=0;
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
if(b[i]+c[j]<=k)ans++;
}
}
cout<<ans<<'\n';
}
B
思路:对于a[1]的操作一定在i为2,同理a[1]为0后,对a[2]的操作一定在i为3,....,最终看最后两个数是否为0即可
查看代码
void solve() {
int n;
cin>>n;
vector<int>ve(n);
for(int i=0;i<n;++i)cin>>ve[i];
for(int i=1;i<n-1;++i){
int c=ve[i-1];
ve[i-1]-=c,ve[i]-=2*c,ve[i+1]-=c;
if(ve[i]<0||ve[i+1]<0){
cout<<"NO\n";
return ;
}
}
if(ve[n-1]>0||ve[n-2]>0)cout<<"NO\n";
else
cout<<"YES\n";
}
C
C - Rudolf and the Ugly String
思路:三种情况,出现map、pie、mapie时操作一次即可
查看代码
void solve() {
int n;
cin>>n;
string s;
cin>>s;
int ans=0;
for(int i=0;i+2<n;++i){
if(i+4<n&&s[i]=='m'&&s[i+1]=='a'&&s[i+2]=='p'&&s[i+3]=='i'&&s[i+4]=='e'){
ans++;
i+=4;
}else if(s[i]=='m'&&s[i+1]=='a'&&s[i+2]=='p')ans++,i+=2;
else if(s[i]=='p'&&s[i+1]=='i'&&s[i+2]=='e')ans++,i+=2;
}
cout<<ans<<'\n';
}
D
思路:用set维护下当前可能在的地方
查看代码
void solve() {
int n,m,x;
cin>>n>>m>>x;
set<int>se;
se.insert(x);
set<int>t;
for(int i=0;i<m;++i){
int d;
char c;
cin>>d>>c;
for(auto v:se){
if(c=='0') {
int y=(v+d)%n;
if(y==0)y=n;
t.insert(y);
}else if(c=='1'){
int y=(v-d+n)%n;
if(y==0)y=n;
t.insert(y);
}else{
int y=(v+d)%n;
if(y==0)y=n;
t.insert(y);
y=(v-d+n)%n;
if(y==0)y=n;
t.insert(y);
}
}
se=t;
t.clear();
}
cout<<se.size()<<'\n';
for(auto v:se)cout<<v<<' ';
cout<<'\n';
}
E
思路:
先求出每行最少需要的支架个数,维护最少的连续k行
对于一行,已知支架之间的最大距离,若当前位置建立支架,用优先队列维护花费最少的上一个可行支架(距离可行),更新在当前位置的最少花费
查看代码
void solve() {
int n,m,k,d;
cin>>n>>m>>k>>d;
vector<vector<int>>ve(n+1,vector<int>(m+1));
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)cin>>ve[i][j];
vector<int>sum(n+1);
for(int i=1;i<=n;++i){
priority_queue<PII,vector<PII>,greater<PII>>q;
q.push({1,1});
for(int j=2;j<=m;++j){
while(q.top().second<j-d-1){
q.pop();
}
if(j==m)sum[i]=q.top().first+ve[i][j]+1;
else q.push({q.top().first+ve[i][j]+1,j});
}
}
int ans=LLONG_MAX,t=0;
for(int i=1;i<=n;++i){
// cout<<sum[i]<<'\n';
t+=sum[i];
if(i>=k){
ans=min(ans,t);
t-=sum[i-k+1];
}
}
cout<<ans<<'\n';
}
F
思路:求a最小的最大差值
由于最多插入一个,若a存在多个最大差值,答案即为最大差值
若只存在一个最大差值r-l,即在(l,r)之间插入,插入后的差值与原第二大差值比较即可
考虑插入的数应该趋近于中间,为mid=l+r>>1
而后枚举d,f应该趋近于mid-d,二分出趋近于mid-d的f,将求出的数与l和r取差值,维护最小差值即可
查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=1e6+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int MAXN=1e8+5;
const double eps=1e-12;
const int dx[4]={-1,1,0,0};
const int dy[4]={0,0,-1,1};
void solve() {
int n,m,k;
cin>>n>>m>>k;
vector<int>a(n),d(m),f(k),dd;
for(int i=0;i<n;++i){
cin>>a[i];
if(i){
dd.push_back(a[i]-a[i-1]);
}
}
for(int i=0;i<m;++i)cin>>d[i];
for(int i=0;i<k;++i)cin>>f[i];
sort(f.begin(),f.end());
std::sort(dd.begin(), dd.end(),greater<int>());
if(n>2&&dd[0]==dd[1])cout<<dd[0]<<'\n';
else{
int l=0,r=0;
for(int i=1;i<n;++i){
if(a[i]-a[i-1]==dd[0]){
l=a[i-1],r=a[i];
break;
}
}
int mid=(l+r)/2;
int mi=dd[0];
for(int i=0;i<m;++i){
auto pr= std::lower_bound(f.begin(), f.end(),mid-d[i]);
auto pl=f.end();
if(pr!=f.begin())pl= prev(pr);
if(pr!=f.end()){
int x=d[i]+*pr;
if(x>l&&x<r){
mi=min(mi,max(x-l,r-x));
}
}
if(pl!=f.end()){
int x=d[i]+*pl;
if(x>l&&x<r){
mi=min(mi,max(x-l,r-x));
}
}
}
int ans;
if(n==2)ans=mi;
else ans=max(mi,dd[1]);
cout<<ans<<'\n';
}
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t=1;
cin>>t;
// init();
while(t--){
solve();
}
return 0;
}
G
思路:一段连续的颜色相同的边形成一条路线,要求s到t的路线个数,可以考虑把每个颜色当作一个节点,边上的端点与这条边的颜色建无向边,相当于如果一条长度为n的路线端点想相互到达只需要花2步,如此一来,可以bfs求s到t的最短路,最后步数除2即为s到t的最少路线个数
查看代码
#include<bits/stdc++.h>
using namespace std;
//#define int long long
//#define int __int128
#define double long double
typedef pair<int,int>PII;
typedef pair<string,int>PSI;
typedef pair<string,string>PSS;
const int N=4e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int MAXN=1e8+5;
const double eps=1e-12;
const int dx[4]={-1,1,0,0};
const int dy[4]={0,0,-1,1};
void solve() {
int n,m;
cin>>n>>m;
vector<array<int,3>>ve(m);
vector<int>g;
for(int i=0;i<m;++i){
int u,v,c;
cin>>u>>v>>c;
ve[i]={u,v,c};
g.push_back(c);
}
sort(g.begin(),g.end());
g.resize(unique(g.begin(),g.end())-g.begin());
vector<vector<int>>f(n+g.size()+1);
for(auto [u,v,c]:ve){
c= std::lower_bound(g.begin(), g.end(),c)-g.begin()+n+1;
f[u].push_back(c);
f[c].push_back(u);
f[v].push_back(c);
f[c].push_back(v);
}
int s,t;
cin>>s>>t;
vector<int>d(n+g.size()+1,-1);
d[s]=0;
queue<int>q;
q.push(s);
while(q.size()){
auto u=q.front();
q.pop();
for(auto v:f[u]){
if(d[v]==-1){
d[v]=d[u]+1;
q.push(v);
}
}
}
cout<<d[t]/2<<'\n';
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t=1;
cin>>t;
// init();
while(t--){
solve();
}
return 0;
}