AC前四题,后面两题骗分(汗),这把小上一波分,还得是ioi赛制,FE后面再补了。。
补一下E,F就算了。。。-----10.15
A. 小红的好数
大于99的直接pass,剩下的判断十位和个位就可以了
using LL =long long;
void solve(){
LL x;
cin>>x;
if(x>99){
cout<<"No";
}
else{
if(x%10==x/10){
cout<<"Yes";
}
else{
cout<<"No";
}
}
}
B 小红的好数组
这题给我感觉挺奇怪的,虽然是暴力,但是写了很久。。。基础还是不扎实。。
分奇偶,然后暴力每个k区间然后判断是否是回文数组
有点史
using LL =long long;
void solve(){
int n,k;
cin>>n>>k;
vector<int> a(n+1,0);
for(int i=1;i<=n;i++) cin>>a[i];
int ans = 0;
if(k%2==0){
int sum = 0;
for(int i=1;i<=n-k+1;i++){
vector<int> q;
sum = 0;
for(int j=i;j<=(i+k-1);j++){
q.push_back(a[j]);
}
for(int r=0;r<(q.size())/2;r++){
if(q[r]!=q[q.size()-1-r]){
sum++;
}
}
if(sum==1){
ans++;
}
}
cout<<ans<<endl;
}
else{
int sum = 0;
for(int i=1;i<=n-k+1;i++){
vector<int> q;
sum = 0;
for(int j=i;j<=(i+k-1);j++){
q.push_back(a[j]);
}
for(int r=0;r<(q.size()-1)/2;r++){
if(q[r]!=q[q.size()-1-r]){
sum++;
}
}
if(sum==1){
ans++;
}
}
cout<<ans<<endl;
}
}
C 小红的矩阵行走
心心念念的bfs来了,好久没做得,c的位置刚刚好^-^
直接bfs开搜就可以,判断右和下两个方向就可以,如果相等,就往后搜,最后看能不能走到a(n,m)这个点,多开几个数组记录一下
vis记录该点是否走过
dis记录走的距离,只要结果不为0都可以
using LL =long long;
int dx[] = {0,1};
int dy[] = {1,0};
void solve(){
int n,m;
cin>>n>>m;
vector<vector<int> > mp(n+1,vector<int>(m+1,0));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>mp[i][j];
}
}
vector<vector<int> > vis(n+1,vector<int>(m+1,0));
vector<vector<int> > dis(n+1,vector<int>(m+1,0));
queue<pair<int,int> > q;
q.push({1,1});
vis[1][1] = 0;
while(!q.empty()){
auto [x,y] = q.front();
q.pop();
for(int i=0;i<2;i++){
int xx = x + dx[i];
int yy = y + dy[i];
if(xx>=1 && xx<=n && yy>=1 && yy<=m && !vis[xx][yy] && mp[x][y]==mp[xx][yy]){
dis[xx][yy] = dis[x][y] + 1;
vis[xx][yy] = 1;
q.push({xx,yy});
}
}
}
if(dis[n][m]){
cout<<"Yes"<<endl;
}
else{
cout<<"No"<<endl;
}
}
D 小红的行列式构造
这题手写一下就可以了,对于(1,3)这个位置可以先判定为0,剩下的利用(1,1)和(1,2)来凑出x
形如
a b 1
1 1 c
1 1 d
最后的值为 a*(d-c) - b*(d-c) == x
化简为 (a-b)*(d-c) == x
可以设 d = 2 c = 1;
这样 a - b = x;
然后已知x,ab随便赋值就可以
我这里因为x==-1时候a会0所以特判了一下
using LL =long long;
void solve(){
int x;
cin>>x;
if(x==-1){
cout<<-3<<" "<<-2<<" "<<1<<endl;
cout<<1<<" "<<1<<" "<<1<<endl;
cout<<1<<" "<<1<<" "<<2<<endl;
return;
}
cout<<x+1<<" "<<1<<" "<<1<<endl;
cout<<1<<" "<<1<<" "<<1<<endl;
cout<<1<<" "<<1<<" "<<2<<endl;
}
E.小红的 red 计数
要点: 求解字符串中字串red字串的数量,考虑以e做为中心点,
分别计算从i点到1的r的数量,和i到n的d的数量,然后相乘
这里省略一万字。。。。b站的讲解很详细,打字说不清楚而且麻烦
新的要点,可以对前缀和进行前缀和!!!
细节偏多,前缀和很多
using LL = long long;
void solve() {
LL n,q;
cin>>n>>q;
string s;
cin>>s;
s = " " + s;
vector<LL> pre(n+1,0),sub(n+2,0),sum(n+1,0),
cnt(n+1,0),pre_pre(n+1,0),pre_sub(n+2,0);
for(int i=1;i<=n;i++){
if(s[i]=='r') pre[i]++;
pre[i] += pre[i-1];
if(s[i]=='e') cnt[i]++;
cnt[i] += cnt[i-1];
}
for(int i=n;i>=0;i--){
sub[i] = sub[i+1];
if(s[i]=='d') sub[i]++;
}
for(int i=1;i<=n;i++){
pre_pre[i] = pre_pre[i-1];
pre_sub[i] = pre_sub[i-1];
if(s[i]=='e'){
pre_pre[i] += pre[i];
}
if(s[i]=='e'){
pre_sub[i] += sub[i];
}
}
for(int i=1;i<=n;i++){
sum[i] = sum[i-1] ;
if(s[i]=='e') sum[i] += pre[i]*sub[i];
}
while(q--){
int l,r;
cin>>l>>r;
LL ans = sum[n] - (sum[r]-sum[l-1]);
// cout<<ans<<endl;
LL cnt2 = cnt[r] - cnt[l-1];
LL x = pre[r] + pre[l-1];
LL y = sub[r+1] + sub[l];
ans += cnt2*x*y;
ans += sum[r] - sum[l-1];
ans -= x*(pre_sub[r] - pre_sub[l-1]);
ans -= y*(pre_pre[r] - pre_pre[l-1]);
cout<<ans<<endl;
}
}