CF540

CF540A

[CSP-S 2023] 密码锁 easy version
对于每一位 考虑向上还是向下转更优即可

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define endl '\n'
#define gc cin.get
#define pc cout.put
const int N=1e4+5;
const int M=1e7+5;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,m,ans;
char s[N],t[N];
signed main(){
    n=read();
    cin>>s+1>>t+1;
    for(int i=1;i<=n;i++)
        ans+=min((s[i]-t[i]+10)%10,(t[i]-s[i]+10)%10);
    cout<<ans<<endl;
    return 0;
}

CF540B

首先看给定的数中小于 \(y\) 的数的数量 如果 \(> \dfrac{n}{2}\) 那中位数就被小的数占了 一定无解
剩下情况在前面+1 后面+中位数即可

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define endl '\n'
#define gc cin.get
#define pc cout.put
const int N=1e5+5;
const int M=1e7+5;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,m,p,k,x,y,ans,a[N];
vector<int>v;
signed main(){
    n=read();k=read();p=read();x=read();y=read();
    for(int i=1;i<=k;i++)a[i]=read(),x-=a[i];
    sort(a+1,a+k+1);
    int num=0;
    for(int i=1;i<=k;i++)num+=a[i]<y;
    if(num>n/2){puts("-1");return 0;}
    for(int i=1;i<=min(n/2-num,n-k);i++)v.push_back(1),x--;
    int l=v.size();
    for(int i=1;i<=n-k-l;i++)v.push_back(y),x-=y;
    if(x<0){puts("-1");return 0;}
    for(auto i:v)cout<<i<<' ';
    return 0;
}

CF540C

大致意思:给定 \(n\times m\) 冰面 碎冰一踩就掉下去 实冰踩一次变成碎冰
要求从终点掉下去

分类讨论:

  • 终点是碎冰:踩到终点即可 bfs判断是否可达
  • 终点是实冰:需要踩完迂回一下 在终点旁边留一块实冰留着之后踩
    然后再不踩这个实冰前提下看看是否能到终点
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define endl '\n'
#define gc cin.get
#define pc cout.put
const int N=1e5+5;
const int M=1e7+5;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,m,a[505][505],b[505][505],sx,sy,tx,ty;
inl bool check(int x,int y){return x>=1&&x<=n&&y>=1&&y<=m;}
int dx[5]={0,0,0,-1,1};
int dy[5]={0,-1,1,0,0};
queue<pair<int,int>>q;
inl bool bfs(int x,int y){
    q.push({x,y});
    while(!q.empty()){
        int xx=q.front().first,yy=q.front().second;q.pop();
        for(int i=1;i<=4;i++){
            int px=xx+dx[i],py=yy+dy[i];
            if(!check(px,py))continue;
            if(px==tx&&py==ty)return 1;
            if(b[px][py])continue;
            b[px][py]=1;q.push({px,py});
        }
    }
    return 0;
}
signed main(){
    n=read();m=read();
    if(n==1&&m==1){puts("NO");return 0;}
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            char c;cin>>c;
            a[i][j]=c=='X';
        }
    }
    sx=read(),sy=read(),tx=read(),ty=read();
    if(a[tx][ty]){
        memcpy(b,a,sizeof b);
        if(bfs(sx,sy))puts("YES");
        else puts("NO");
        return 0;
    }
    for(int i=1;i<=4;i++){
        int px=tx+dx[i],py=ty+dy[i];
        if(!check(px,py))continue;
        if(a[px][py])continue;
        memcpy(b,a,sizeof b);
        b[px][py]=1;
        if(bfs(sx,sy)){puts("YES");return 0;}
    }
    puts("NO");
    return 0;
}

CF540D

题意:有三个人,老闭灯、才卓青和james1,老闭灯能吃才卓青,才卓青能吃James1,james1能吃老闭灯。
各有 \(r\) 个老闭灯、 \(s\) 个才卓青和 \(p\) 只James1,每两个人等概率相遇,不同的人必然被吃一个,问最后每个人活下来的概率。

考虑dp。
\(f_{i,j,k}\) 表示老闭灯、才卓青和james1分别有 \(i,j,k\) 个的概率

\(f_{r,s,p}=1\)

所有情况即为 \(i\times j+i\times k+j\times k\)
转移:
\(f_{i-1,j,k}=f_{i,j,k}\times i\times k/tot\)
\(f_{i,j-1,k}=f_{i,j,k}\times i\times j/tot\)
\(f_{i,j,k-1}=f_{i,j,k}\times j\times k/tot\)

老闭灯的答案即为 \(\sum\limits_{i=1}^r f_{i,0,0}\)
其他人同理 \(\sum\limits_{i=1}^s f_{0,i,0}\) \(\sum\limits_{i=1}^p f_{0,0,i}\)

CF540E

对于交换后的元素 求逆序对是很简单的:树状数组即可。
考虑没交换的和交换后的元素之间贡献:
不管换前换后,贡献都为位置前后区间中没换的元素个数(手玩一下就可以发现)。
位置前后区间中没换的元素个数 前缀和扫一遍即可。
但蒟蒻手比脑子快 先写了动态开点线段树。。稳居最劣解

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline
#define endl '\n'
#define int ll
#define gc cin.get
#define pc cout.put
const int N=4e5+5;
const int M=1e7+5;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,a[N],b[N],lsh[N],p[N],rt,ans,t,fp[N];
struct segment_tree{
    int s[M],ls[M],rs[M],cnt;
    #define mid (l+r>>1)
    inl void modify(int &k,int l,int r,int x){
        if(!k)k=++cnt;s[k]++;
        if(l==r)return;
        if(x<=mid)modify(ls[k],l,mid,x);
        else modify(rs[k],mid+1,r,x);
    }
    inl int query(int k,int l,int r,int x,int y){
        if(!k)return 0;
        if(x<=l&&r<=y)return s[k];
        int ans=0;
        if(x<=mid)ans+=query(ls[k],l,mid,x,y);
        if(y>mid)ans+=query(rs[k],mid+1,r,x,y);
        return ans;
    }
}SGT;
struct binary_index_tree{
    int c[N];
    inl void add(int x){
        for(;x<=t;x+=x&-x)c[x]++;
    }
    inl int query(int x){
        int ans=0;
        for(;x;x-=x&-x)ans+=c[x];
        return ans;
    }
}BIT;
signed main(){
    n=read();
    for(int i=1;i<=n;i++){
        a[i]=lsh[i]=read();
        b[i]=lsh[i+n]=read();
    }
    sort(lsh+1,lsh+(n<<1)+1);
    t=unique(lsh+1,lsh+(n<<1)+1)-lsh-1;
    for(int i=1;i<=n;i++){
        a[i]=lower_bound(lsh+1,lsh+t+1,a[i])-lsh;
        b[i]=lower_bound(lsh+1,lsh+t+1,b[i])-lsh;
    }
    for(int i=1;i<=t;i++)p[i]=i;
    for(int i=1;i<=n;i++)swap(p[a[i]],p[b[i]]);
    for(int i=1;i<=t;i++){
        ans+=i-1-BIT.query(p[i]);
        BIT.add(p[i]);
    }
    for(int i=1;i<=t;i++)fp[p[i]]=i;
    for(int i=1;i<=t;i++)
        SGT.modify(rt,1,1e9,lsh[i]);
    for(int i=1;i<=t;i++){
        if(lsh[fp[i]]>lsh[i])ans+=lsh[fp[i]]-lsh[i]+1-SGT.query(rt,1,1e9,lsh[i],lsh[fp[i]]);
        else ans+=lsh[i]-lsh[fp[i]]+1-SGT.query(rt,1,1e9,lsh[fp[i]],lsh[i]);
    }
    cout<<ans<<endl;
    return 0;
}
posted @ 2023-12-06 14:14  xiang_xiang  阅读(6)  评论(0编辑  收藏  举报