ABC401
| Rank | 2609th / 13187 |
|---|---|
| Performance | 1109 |
| Rating Change | 70 → 239 (+169) Highest! |
| Grading | 12 Kyu → 10 Kyu |
A
判断 \(S\) 是否满足 \(200 \le S \le 299\),送分题不解释。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
constexpr int N=0;
int main()
{
int s;
cin>>s;
if(s>=200&s<=299) cout<<"Success";
else cout<<"Failure";
return 0;
}
B
模拟即可,设置一个变量判断有没有登录,送分题不解释。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
constexpr int N=0;
int main()
{
int Q,ans=0;
cin>>Q;
bool is=0;
string s;
while(Q--)
{
cin>>s;
if(s=="login") is=1;
if(s=="logout") is=0;
if(s=="private")
{
if(is==0) ans++;
}
}
cout<<ans;
return 0;
}
C
题目
给定正整数 \(n\) 和 \(k\),定义长度为 \(n+1\) 的序列 \(a = (a_0, a_1, \ldots, A_n)\) 如下:
- 当 \(0 \le i \le k\) 时,\(a_i = 1\);
- 当 \(i \ge k\) 时,\(a_i=a_{i-k}+a_{i-k+1}+\ldots+a_{i-1}\).
求 \(a_n \bmod 10^9\) 。
思路
当 \(0 \le i < k\) 时,\(a_i\) 全部赋值为 \(1\) 即可。
当 \(i \ge k\) 时,由题意知 \(a_i=\sum _{i=k}^{i-1}\),不难发现可以用前缀和维护。设 \(S_i\) 为 \(\sum _{i=0}^i\),则有 \(a_i=S_{i-1}-S_{i-k-1}\)。注意由于要取模,所以可能会出现负数,此时加上模数即可。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
constexpr int N=1e6+7;
constexpr int mod=1e9;
ll a[N],s[N];
int n,k;
inline ll sigma(int l,int r)
{
return s[r]+mod+mod-s[l-1];
}
int main()
{
cin>>n>>k;
a[0]=1;
s[0]=1;
for(int i=1;i<k;i++)
{
a[i]=1;
s[i]=(s[i-1]+a[i])%mod;
}
for(int i=k;i<=n;i++)
{
a[i]=(sigma(i-k,i-1)%mod);
s[i]=(a[i]+s[i-1])%mod;
}
// for(int i=0;i<=n;i++) cerr<<a[i]<<' ';
// cerr<<endl;
// for(int i=0;i<=n;i++) cerr<<s[i]<<' ';
cout<<a[n];
return 0;
}
/*
当0<=i<k时,a[i]=1
否则a[i]=a[i-1]+a[i-2]+...+a[i-k]
*/
D
题目
给定一个长为 \(n\) 且仅由字符 .o? 构成的字符串 \(S\),现将 ? 填上 . 或 o 使得新字符串满足以下要求:
- 字符
o的个数恰好为 \(k\); - 没有两个字符
o相邻。
如果能确定该问号位置能填 . 或 o 则直接输出 . 或 o,否则输出 ?。
思路
先将 \(k\) 减去原本有的 o 的个数,得到还需要放置 o 的个数后,分三种情况讨论:
- 如果一个
o都不用放,则问号全部填.即可。 - 如果问号中必须全部放满
o,则对于一个问号串(即连续的一串问号)有以下规则:- 如果问号串的长度为奇数,则隔一个放一个
o,比如o.oo.o.o; - 如果问号串的长度为偶数,则全部填问号。因为没法确定放
o的位置,可以像o.o.这样或者像.o.o这样放。
- 如果问号串的长度为奇数,则隔一个放一个
- 否则,全部填满问号即可。
代码
/*
vis[x]为下标为x开头的问号连通块中含有的问号个数
饱和状态就是全部都得放满o的状态
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
constexpr int N=2e5+7;
int n,k;
string s;
int vis[N];
inline int bfs(int x) //找问号连通块
{
int cnt=0;
for(int i=x;i<n;i++)
{
if(s[i]!='?') break;
vis[i]=1;
cnt++;
}
vis[x]=cnt;
return (cnt+1)/2;
}
inline void setx(int idx,char c) //要防止越界
{
if(idx>=0&&idx<n) s[idx]=c;
}
inline bool chkx(int idx,char c)
{
if(idx>=0&&idx<n) return (s[idx]==c);
else return false;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin>>n>>k>>s;
for(int i=0;i<n;i++)
{
if(s[i]=='o')
{
setx(i-1,'.');
setx(i+1,'.');
k--;
}
}
// cerr<<s;
int mx=0; //最多能放多少个
for(int i=0;i<n;i++)
{
if(s[i]=='?'&&!vis[i])
{
int res=bfs(i);
mx+=res;
}
}
if(k==0) //啥都不用放了
{
for(int i=0;i<n;i++)
{
if(s[i]=='?') cout<<'.';
else cout<<s[i];
}
}
else if(mx==k) //饱和状态
{
for(int i=0;i<n;i++)
{
if(s[i]=='?')
{
if(vis[i]%2) //奇数个问号
{
int R=i+vis[i];
char lst=((i==0)?'.':s[i-1]);
for(;i<R;i++)
{
if(lst=='.') cout<<'o';
else cout<<'.';
if(lst=='.') lst='o';
else lst='.';
}
i--;
}
else
{
int R=i+vis[i];
for(;i<R;i++)
{
cout<<'?';
}
i--;
}
}
else cout<<s[i];
}
}
else
{
cout<<s;
}
return 0;
}

浙公网安备 33010602011771号