winter 2024 day3

SMU Winter 2024 round 1

AB. Sum of Medians

思路:贪心的想,只有中位数有贡献,并且知道了中位数的位置以及中位数左边的数的个数 l 和中位数右边的数的个数 r ,那么对于一个不递减的数组,要取出最大的中位数,即取出l个最小的数和r个最大的数,中位数即为第r+1大的数。直到数取完为止。

#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=3e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int MAXN=1e8+5;
const double eps=1e-6;


void solve() {
    int n,k;cin>>n>>k;
    vector<int>ve(n*k+1);
    for(int i=1;i<=n*k;++i)cin>>ve[i];
    int ans=0;
    int rc=n/2,lc=n-rc-1;
    int l=1,r=n*k;
    while(r-l+1>=n){
        ans+=ve[r-rc];
        r-=rc+1;
        l+=lc;
    }
    cout<<ans<<'\n';
}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

BB. Repainting Street

思路:由于c的范围很小,直接暴力枚举每一种c需要的粉刷次数

#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=3e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int MAXN=1e8+5;
const double eps=1e-6;


void solve() {
    int n,k;cin>>n>>k;
    vector<int>ve(n);
    set<int>se;
    for(int i=0;i<n;++i){
        cin>>ve[i];
        se.insert(ve[i]);
    }
    int ans=INF;
    for(auto v:se){
        int cnt=0;
        for(int i=0;i<n;++i){
            if(ve[i]!=v)cnt++,i+=k-1;
        }
        ans=min(ans,cnt);
    }
    cout<<ans<<'\n';
}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

CJ. Let's Play Jigsaw Puzzles!

思路:由于每个数的四个方向上的数都知道,那么找出左上角的数即可一行行枚举推出。也可以bfs或者dfs

#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=3e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int MAXN=1e8+5;
const double eps=1e-6;

int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
void solve() {
    int n;cin>>n;
    int m=n*n;
    vector<vector<int>>ve(m+1,vector<int>(4));
    int s;
    for(int i=1;i<=m;++i){
        for(int j=0;j<4;++j){
            cin>>ve[i][j];
        }
        if(ve[i][0]==-1&&ve[i][2]==-1)s=i;
    }
    vector<vector<int>>g(n+1,vector<int>(n+1));
    vector<vector<int>>st(n+1,vector<int>(n+1));
    g[1][1]=s;
    queue<PII>q;
    q.push({1,1});
    st[1][1]=1;
    while(q.size()){
        auto t=q.front();q.pop();
        for(int i=0;i<4;++i){
            if(ve[g[t.first][t.second]][i]==-1)continue;
            int xx=t.first+dx[i],yy=t.second+dy[i],id=ve[g[t.first][t.second]][i];
            if(!st[xx][yy]){
                st[xx][yy]=1;
                g[xx][yy]=id;
                q.push({xx,yy});
            }
        }
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            cout<<g[i][j];
            if(j!=n)cout<<' ';
        }
        cout<<'\n';
    }
}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
//    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

DC. Bouncing Ball

思路:也是暴力枚举删除个数,由于k是不变的,那每个位置对应跳到的位置也是不变的,即用位置%k对它们进行分类,可以预处理出从每个位置开始跳后的用时

#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=3e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int MAXN=1e8+5;
const double eps=1e-6;


void solve() {
    int n,p,k;cin>>n>>p>>k;
    string s;cin>>s;
    int x,y;cin>>x>>y;
    int ans=INT32_MAX;
    vector<int>g(k+5);
    for(int i=0;i<s.size();++i){
        if(i+1>=p&&s[i]=='0')g[i%k]++;
    }
    for(int i=0,st=p-1;i<n&&st<n;++i,st++){
        int cnt=i*y+g[st%k]*x;
        ans=min(ans,cnt);
        g[st%k]-=s[st]=='0';
    }
    cout<<ans<<'\n';
}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

EC1. Binary Table (Easy Version)

思路:同下题

#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=3e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int MAXN=1e8+5;
const double eps=1e-6;
int dx[10]={-1,-1,0,1,1,1,0,-1,0};
int dy[10]={0,1,1,1,0,-1,-1,-1,0};
int d[17][3]={{},{0,6,7},{0,7,8},{0,6,8},{6,7,8},
              {0,1,8},{0,1,2},{1,2,8},{0,2,8},
              {5,6,8},{4,6,8},{4,5,8},{4,5,6},
              {2,4,8},{2,3,8},{2,3,4},{3,4,8}};
void solve() {
    int n,m;
    cin>>n>>m;
    vector<vector<int>>ve(n+5,vector<int>(m+5));
    for(int i=1;i<=n;++i){
        string s;
        cin>>s;
        for(int j=1;j<=m;++j){
            ve[i][j]=s[j-1]-'0';
        }
    }
    vector<vector<PII>>ans;
    auto add=[&](int x,int y,int p){
        vector<PII>t;
        for(int i=0;i<3;++i){
            int xx=x+dx[d[p][i]],yy=y+dy[d[p][i]];
            ve[xx][yy]^=1;
            t.push_back({xx,yy});
        }
        ans.push_back(t);
    };
    if(n%2){
        for(int i=1;i<m;++i)
            if(ve[n][i]==1)add(n,i,5);
        if(ve[n][m]==1)add(n,m,2);
    }
    if(m%2){
        if(ve[1][m]==1)add(1,m,9);
        for(int i=2;i<n;++i)
            if(ve[i][m]==1)add(i,m,4);
        if(ve[n][m]==1)add(n,m,4);
    }
    auto sum=[&](int x,int y){
        return ve[x][y]+ve[x][y-1]+ve[x-1][y]+ve[x-1][y-1];
    };
    auto to3=[&](int x,int y){
        if(ve[x][y]==0)add(x,y,1);
        else if(ve[x-1][y]==0)add(x,y,4);
        else if(ve[x][y-1]==0)add(x,y,2);
        else add(x,y,3);
    };
    auto to2=[&](int x,int y){
        if(ve[x][y]==1&&ve[x-1][y]==1)add(x,y,4);
        else if(ve[x-1][y-1]==1&&ve[x][y-1]==1)add(x,y,2);
        else if(ve[x-1][y-1]==1&&ve[x-1][y]==1)add(x,y,3);
        else if(ve[x][y-1]==1&&ve[x][y]==1)add(x,y,2);
        else if(ve[x-1][y-1]==1&&ve[x][y]==1)add(x,y,3);
        else if(ve[x][y-1]==1&&ve[x-1][y]==1)add(x,y,2);
        to3(x,y);
    };
    auto to1=[&](int x,int y){
        if(ve[x][y]==1)add(x,y,3);
        else if(ve[x][y-1]==1)add(x,y,4);
        else if(ve[x-1][y]==1)add(x,y,2);
        else add(x,y,1);
        to2(x,y);
    };
    auto to4=[&](int x,int y){
        add(x,y,3);
        to1(x,y);
    };
    for(int i=2;i<=n;i+=2){
        for(int j=2;j<=m;j+=2){
            int c=sum(i,j);
            if(c==4)to4(i,j);
            else if(c==3)to3(i,j);
            else if(c==2)to2(i,j);
            else if(c==1)to1(i,j);
        }
    }
    cout<<ans.size()<<'\n';
    for(auto v:ans){
        for(int i=0;i<3;++i){
            cout<<v[i].first<<' '<<v[i].second;
            if(i!=2)cout<<' ';
        }
        cout<<'\n';
    }
}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

FC2. Binary Table (Hard Version)

思路:模拟。可以只看大小为4的正方形的情况,发现正方形的所有情况都可以在不超过4次操作变成全0。对于n或m为奇数时,对最后一行或一列直接操作变成0就好,次数平均每个格子一次

#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=3e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int MAXN=1e8+5;
const double eps=1e-6;
int dx[10]={-1,-1,0,1,1,1,0,-1,0};
int dy[10]={0,1,1,1,0,-1,-1,-1,0};
int d[17][3]={{},{0,6,7},{0,7,8},{0,6,8},{6,7,8},
              {0,1,8},{0,1,2},{1,2,8},{0,2,8},
              {5,6,8},{4,6,8},{4,5,8},{4,5,6},
              {2,4,8},{2,3,8},{2,3,4},{3,4,8}};
void solve() {
    int n,m;
    cin>>n>>m;
    vector<vector<int>>ve(n+5,vector<int>(m+5));
    for(int i=1;i<=n;++i){
        string s;
        cin>>s;
        for(int j=1;j<=m;++j){
            ve[i][j]=s[j-1]-'0';
        }
    }
    vector<vector<PII>>ans;
    auto add=[&](int x,int y,int p){
        vector<PII>t;
        for(int i=0;i<3;++i){
            int xx=x+dx[d[p][i]],yy=y+dy[d[p][i]];
            ve[xx][yy]^=1;
            t.push_back({xx,yy});
        }
        ans.push_back(t);
    };
    if(n%2){
        for(int i=1;i<m;++i)
            if(ve[n][i]==1)add(n,i,5);
        if(ve[n][m]==1)add(n,m,2);
    }
    if(m%2){
        if(ve[1][m]==1)add(1,m,9);
        for(int i=2;i<n;++i)
            if(ve[i][m]==1)add(i,m,4);
        if(ve[n][m]==1)add(n,m,4);
    }
    auto sum=[&](int x,int y){
        return ve[x][y]+ve[x][y-1]+ve[x-1][y]+ve[x-1][y-1];
    };
    auto to3=[&](int x,int y){
        if(ve[x][y]==0)add(x,y,1);
        else if(ve[x-1][y]==0)add(x,y,4);
        else if(ve[x][y-1]==0)add(x,y,2);
        else add(x,y,3);
    };
    auto to2=[&](int x,int y){
        if(ve[x][y]==1&&ve[x-1][y]==1)add(x,y,4);
        else if(ve[x-1][y-1]==1&&ve[x][y-1]==1)add(x,y,2);
        else if(ve[x-1][y-1]==1&&ve[x-1][y]==1)add(x,y,3);
        else if(ve[x][y-1]==1&&ve[x][y]==1)add(x,y,2);
        else if(ve[x-1][y-1]==1&&ve[x][y]==1)add(x,y,3);
        else if(ve[x][y-1]==1&&ve[x-1][y]==1)add(x,y,2);
        to3(x,y);
    };
    auto to1=[&](int x,int y){
        if(ve[x][y]==1)add(x,y,3);
        else if(ve[x][y-1]==1)add(x,y,4);
        else if(ve[x-1][y]==1)add(x,y,2);
        else add(x,y,1);
        to2(x,y);
    };
    auto to4=[&](int x,int y){
        add(x,y,3);
        to1(x,y);
    };
    for(int i=2;i<=n;i+=2){
        for(int j=2;j<=m;j+=2){
            int c=sum(i,j);
            if(c==4)to4(i,j);
            else if(c==3)to3(i,j);
            else if(c==2)to2(i,j);
            else if(c==1)to1(i,j);
        }
    }
    cout<<ans.size()<<'\n';
    for(auto v:ans){
        for(int i=0;i<3;++i){
            cout<<v[i].first<<' '<<v[i].second;
            if(i!=2)cout<<' ';
        }
        cout<<'\n';
    }
}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

GD. Walker

思路:

(p1<p2)首先p1和p2的的移动情况有:

1.p1或p2独自走完全程

2.p1走到n,p2走到0

3.在[p1,p2]之间的一点x,在同一时间p1走遍0到x,p2走遍x到n

解释下为什么,这里涉及到了物理问题。

为什么要在[p1,p2]之间定一点x,如果x是在[0,p1],说明p1和p2同时到达了x,并且此时p2走的路程一定是大于p1的,也就是说v2>v1,那么剩下的[0,x]一定是p2走的,也就是相当于p2走完了全程。同理如果x是在[p2,n],也是相当于p1走完了全程。

这里对于第三种情况,二分x,如果p1的用时t1小于p2的用时,说明x要往右移,反之x往左。

同一时间是为了用时最少。

#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=3e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int MAXN=1e8+5;
const double eps=1e-12;
void solve() {
    double n,p1,v1,p2,v2;
    cin>>n>>p1>>v1>>p2>>v2;
    if(p1>p2)swap(p1,p2),swap(v1,v2);
    double ans;
    auto getT=[](double l,double r,double p,double v){
        return (min(p-l,r-p)+r-l)/v;
    };
    ans=min(getT(0,n,p1,v1),getT(0,n,p2,v2));
    double l=p1,r=p2,s=2;
    auto check=[p1,v1,getT,n,p2,v2](double x){
        double t1=getT(0,x,p1,v1);
        double t2=getT(x,n,p2,v2);
        return t1<t2;
    };
    double x,k=100;
    while(k--){
        double mid=(l+r)/s;
        if(check(mid))l=mid;
        else r=mid;
    }
    x=l;
    double t=max(getT(0,x,p1,v1),getT(x,n,p2,v2));
    ans=min(ans,t);
    ans=min(ans,max(getT(p1,n,p1,v1),getT(0,p2,p2,v2)));
    cout<<fixed<<setprecision(10)<<ans<<'\n';
}

signed main(){
//    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

HM. Gitignore

思路:将不能忽略的所有文件路径用哈希表存储,对于要忽略的,遍历其路径,直到当前找到的文件夹名不在不能忽略的哈希表存储中,若该文件夹名已在忽略名单中,则直接跳过;若不在则将其加入忽略名单,并且答案加一;

#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=3e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int MAXN=1e8+5;
const double eps=1e-6;
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};

void solve() {
    int n,m;cin>>n>>m;
    vector<string>a(n),b(m);
    for(int i=0;i<n;++i)cin>>a[i];
    for(int i=0;i<m;++i)cin>>b[i];
    map<string,int>mp;
    for(int i=0;i<m;++i){
        string c;
        for(int j=0;j<b[i].size();++j){
            c.push_back(b[i][j]);
            if(b[i][j]=='/'){
                mp[c]=1;
            }
        }
        mp[c]=1;
    }
    int ans=0;
    for(int i=0;i<n;++i){
        string c;
        bool ok=false;
        for(int j=0;j<a[i].size();++j){
            c.push_back(a[i][j]);
            if(a[i][j]=='/'){
                if(!mp.count(c))mp[c]=2,ans++;
                if(mp[c]==1)continue;
                ok=true;
                break;
            }
        }
        if(!ok&&mp[c]!=2)ans++;
    }
    cout<<ans<<'\n';
}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

IC. Engineer Artem

思路:一个数要与四个方向上的数不同,对矩阵整体来看,其实可以分成两批,在同一批的数可以相同,那么可以想到奇偶性,把两批的数分别变成同批同奇偶性即可

#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=3e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int MAXN=1e8+5;
const double eps=1e-6;
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};

void solve() {
    int n,m;cin>>n>>m;
    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];
            if(i%2){
                if(j%2&&ve[i][j]%2==0)ve[i][j]++;
                else if(j%2==0&&ve[i][j]%2)ve[i][j]++;
            }else{
                if(j%2&&ve[i][j]%2)ve[i][j]++;
                else if(j%2==0&&ve[i][j]%2==0)ve[i][j]++;
            }
        }
    }
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=m;++j){
            cout<<ve[i][j];
            if(j!=m)cout<<' ';
        }cout<<'\n';
    }
}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

JD. Good Triple

思路:可以打表看看,发现没有找到满足条件的情况的长度一定不超过8,那么对于每个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=3e5+5,INF=0x3f3f3f3f,Mod=1e9+7,mod=998244353;
const int MAXN=1e8+5;
const double eps=1e-6;
void solve() {
    string s;
    cin>>s;
    int n=s.size();
    s=' '+s;
    int ans=0;
    for(int l=1,r=l+2;r<=n;++l){
        bool ok=false;
        while(r<=n){
            for(int d=1;l+2*d<=r;++d){//间距
                for(int st=l;st+2*d<=r;++st)//起点
                {
                    if(s[st]==s[st+d]&&s[st]==s[st+2*d]){
                        ok=true;break;
                    }
                }
                if(ok&&r<=n){
                    ans+=n-r+1;
                    break;
                }
            }
            if(ok)break;
            r++;
        }
    }
    cout<<ans;
}

signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t=1;
//    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}
View Code

 

 

 

posted @ 2024-01-25 13:27  bible_w  阅读(1)  评论(0编辑  收藏  举报