A
从两个数组中各选一个数,求两数之和小于等于k的情况数。n,m很小。
int n,m,k;cin>>n>>m>>k;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=m;i++)
cin>>b[i];
ll ans = 0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(a[i]+b[j]<=k)
ans++;
cout<<ans<<endl;
B
模拟、判断
int n;cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
int ok = 1;
for(int i=1;i<=n-2&&ok;i++){
if(a[i+1] >= 2*a[i] && a[i+2]>=a[i]){
a[i+1]-=2*a[i];
a[i+2]-=a[i];
a[i]-=a[i];
}
else
ok = 0;
}
for(int i=1;i<=n;i++){
if(a[i]!=0) ok=0;
}
if(ok)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
C
统计有几个“pie”和几个“map”
int n;cin>>n;
string s;cin>>s;
int ans = 0;
for (int i=0;i<n;i++) {
if (i+3<=n && s.substr(i,3)=="pie")
ans++;
if (i+3<=n && s.substr(i,3)=="map")
ans++;
if (i+5<=n && s.substr(i,5)=="mapie")
ans--;
}
cout<<ans<<endl;
D
dfs会t,因为是按照顺序的,是让两个set来回模拟
set<int> ans;
set<int> now;
int n,m,x;cin>>n>>m>>x;
now.insert(x);
for(int i=1;i<=m;i++){
int a; char b; cin>>a>>b;
if(b != '0'){
for(auto j : now)
if((j-a+n)%n == 0)
ans.insert(n);
else
ans.insert((j-a+n)%n);
}
if(b != '1'){
for(auto j : now)
if((j+a)%n == 0)
ans.insert(n);
else
ans.insert((j+a)%n);
}
now = ans;
ans.clear();
}
cout<<now.size()<<endl;
for(auto i : now)
cout<<i<<" ";
cout<<endl;
E
先求出每一行的最小值:单调队列(滑动窗口),然后前缀和求连续。
int t;cin>>t;
while(t--){
ll n,m,k,d;cin>>n>>m>>k>>d;
for(int i=1;i<=n;i++){
cin>>a[1];
ll l = 1 , r = 1;
f[1] = 1;//第一个位置总是1
q[1] = 1;
for(int i=2;i<=m;i++){
cin>>a[i];
f[i] = 1e18;
while(l <= r && i-q[l]-1 > d)//左边界
l++;
f[i] = f[q[l]] + a[i] + 1;//求和
while(l <= r && f[q[r]] > f[i])//右边界
r--;
q[++r] = i;
}
s[i] = s[i-1] + f[m];//前缀和
}
ll mi = 1e18;
for(int i=k;i<=n;i++)
mi = min(mi , s[i] - s[i-k]);
cout<<mi<<endl;
}