今天的封面原图 画师DAIKA!! 队友最近老发 去d了一下 大家都来d
久违的单人场 掉分了 D题被硬控一小时 但是也学到了全新guess点 早知道写EF的话应该反而有不小的概率开出来 那么我们话不多说就进入正文吧
AtCoder Beginner Contest 380
A - 123233
题意
给一个长度为6的字符串,满足1个1,2个2,3个3就输出Yes
复盘
最后一个else忘加if甚至wa了一发
代码
#include <bits/stdc++.h>
#define maxOf(a) *max_element(a.begin(),a.end())
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void solve()
{
string s;
cin>>s;
int one=0,two=0,three=0;
for(int i=0;i<s.size();i++)
{
if(s[i]=='1')
one++;
else if(s[i]=='2')
two++;
else if(s[i]=='3')
three++;
}
if(one==1 and two==2 and three==3)
{
cout<<"Yes";
}
else
{
cout<<"No";
}
}
int main()
{
int T=1;
//scanf("%d",&T);
while(T--)
{
solve();
}
return 0;
}
B - Hurdle Parsing
题意
输出每一段连续的-
的个数
代码
#include <bits/stdc++.h>
#define maxOf(a) *max_element(a.begin(),a.end())
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void solve()
{
string s;
cin>>s;
vector<int> a;
int now_cnt=0;
for(int i=1;i<s.size()-1;i++)
{
if(s[i]=='-')
now_cnt++;
else
{
a.push_back(now_cnt);
now_cnt=0;
}
}
a.push_back(now_cnt);
for(auto x:a)
cout<<x<<" ";
cout<<endl;
}
int main()
{
int T=1;
//scanf("%d",&T);
while(T--)
{
solve();
}
return 0;
}
C - Move Segment
题意
将第k段连续的1放在紧接着第k-1段连续的1的后面
代码
#include <bits/stdc++.h>
#define maxOf(a) *max_element(a.begin(),a.end())
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void solve()
{
int n,k;
scanf("%d%d",&n,&k);
string s;
cin>>s;
vector<int> one,zero;
for(int i=0;i<n;i++)
{
if(i==0 or s[i]!=s[i-1])
{
if(s[i]=='0')
{
zero.push_back(i);
}
else
{
one.push_back(i);
}
}
}
int cnt=0;
if(s[0]=='0')
{
int i;
for(i=one[k-1];i<n and s[i]!='0';i++)
{
s[i]='0';
cnt++;
}
for(i=zero[k-1];i<zero[k-1]+cnt;i++)
{
s[i]='1';
}
}
else
{
int i;
for(i=one[k-1];i<n and s[i]!='0';i++)
{
s[i]='0';
cnt++;
}
for(i=zero[k-2];i<zero[k-2]+cnt;i++)
{
s[i]='1';
}
}
cout<<s<<endl;
}
int main()
{
int T=1;
//scanf("%d",&T);
while(T--)
{
solve();
}
return 0;
}
D - Strange Mirroring
题意
对字符串做如下操作无限次
- 先把原本的字符串
S
大小写调换得到一个新的字符串T
- 将S更新为
S+T
复盘
赛时写的是一个递归往前推的过程,不知道为什么一直RE,理论上不会的啊
#include <bits/stdc++.h>
#define maxOf(a) *max_element(a.begin(),a.end())
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
//01101001100101101001011001101001
char change(char c)
{
if(c>='a'&&c<='z')
return c-'a'+'A';
else
return c-'A'+'a';
}
int pre[33]={0,0,1,1,0,
1,0,0,1,
1,0,0,1,
0,1,1,0,
1,0,0,1,
0,1,1,0,
0,1,1,0,
1,0,0,1,};
map<ll,int> mp;
int zhao(ll x)
{
if(mp[x]!=0)
return mp[x];
if(x<=32 && pre[x]==1)
return mp[x]=1;
if(x<=32 && pre[x]==0)
return mp[x]=-1;
//找到第一个小于等于x的2的幂
ll now=1;
while(now<=x)
now*=2;
now/=2;
ll del=x-now-1;
if(zhao(now-del)==1)
return mp[x]=-1;
else
return mp[x]=1;
}
int main()
{
string s;
cin>>s;
int len=s.size();
int n;
cin>>n;
vector<ll> a(n);
for(int i=0;i<n;i++)
cin>>a[i];
vector<char> ans(n);
for(int i=0;i<n;i++)
{
ll now=a[i];
ll chu=now/len;
ll yu=now%len;
if(yu==0)
{
chu--;
yu=len;
}
chu++;
int status=zhao(chu);
if(status==-1)
ans[i]=s[yu-1];
else
ans[i]=change(s[yu-1]);
}
for(auto x:ans)
cout<<x<<" ";
cout<<endl;
return 0;
}
思路
上面的代码虽然不对,但是看最前面的注释01101001100101101001011001101001
,发现我要干什么了嘛,假设第一次重复是原始状态也就是0,第一次就是1,第二次是1,第三次是0,以此类推
如果你还没看出来的话,我们用二进制表示这些下标,分别是
0
1
10
11
100
101
110
111
跟二进制表示下1的个数有关,这也是我刚学到的全新guess点
代码
#include <bits/stdc++.h>
#define maxOf(a) *max_element(a.begin(),a.end())
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
char change(char c)
{
if(c>='a' and c<='z')
return c-32;
return c+32;
}
void solve()
{
string s;
cin>>s;
vector<char> ans;
int q;
cin>>q;
int len=s.size();
while(q--)
{
ll t;
cin>>t;
// printf("%d\n",cnt);
ll chu=t/len;
ll yu=t%len;
if(yu==0)
{
yu=len;
chu--;
}
ll cnt=popcount((unsigned long long)(chu));
if(cnt%2==0)
{
ans.push_back(s[yu-1]);
}
else
{
ans.push_back(change(s[yu-1]));
}
}
for(auto x:ans)
{
cout << x << " ";
}
}
int main()
{
int T=1;
//scanf("%d",&T);
while(T--)
{
solve();
}
return 0;
}
E - 1D Bucket Tool
题意
一行中有
N
N
N 个单元格,编号为
1
1
1 至
N
N
N 。
在每个
1
≤
i
<
N
1 \leq i < N
1≤i<N 单元格中,
i
i
i 和
i
+
1
i+1
i+1 单元格相邻。
最初,
i
i
i 单元格被涂上了颜色
i
i
i 。
给您
Q
Q
Q 个查询。请按顺序处理它们。每个查询属于以下两种类型之一。
1 x c
:将以下单元格重涂为颜色 c c c :通过重复移动到与当前单元格颜色相同的相邻单元格,从单元格 x x x 到达的所有可到达单元格。2 c
:打印涂上颜色 c c c 的单元格数量。
思路
一片方格一旦某一个瞬间变成了同一个颜色,那么后续永远都是同时变色了,我们可以维护一个set存储每片方格的隔断,给每个点都可以二分查找得到这一段,然后再一起修改,改完之后再往左往右更新隔断
代码
#include <bits/stdc++.h>
#define maxOf(a) *max_element(a.begin(),a.end())
#define minOf(a) *min_element(a.begin(),a.end())
#define all(a) a.begin(),a.end()
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void solve()
{
int n,q;
scanf("%d%d",&n,&q);
vector<int> ans(n,1);
set<pair<int,int>> st;
for(int i=0;i<n;i++)
{
st.insert({i,i});
}
st.insert({-1,2e9});
st.insert({n,2e9});
while(q--)
{
int cmd;
scanf("%d",&cmd);
if(cmd==1)
{
int x,c;
scanf("%d%d",&x,&c);
x--;c--;
auto it=st.lower_bound({x,2e9});
auto[R,Rc]=*it;
auto[L,Mc]=*--it;
auto[_,Lc]=*--it;
ans[Mc]-=R-L;
ans[c]+=R-L;
it++;
it=st.erase(it);
if(c==Rc)
it=st.erase(it);
if(c!=Lc)
st.insert({L,c});
}
else
{
int c;
scanf("%d",&c);
c--;
printf("%d\n",ans[c]);
}
}
}
int main()
{
int T=1;
//scanf("%d",&T);
while(T--)
{
solve();
}
return 0;
}