2024.11.30 Rayan Programming Contest 2024 - Selection (Codeforces Round 989, Div. 1 + Div. 2)

EssnSlaryt發表於2024-12-01

Solved: 5/10

Rank: 329


數數水平真的太差了。。。


A. King Keykhosrow's Mystery

題意:給 \(a,b\),求最小的 \(m\) 使得 \(m\bmod a = m\bmod b\)

輸出最小公倍數即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

void solve(){
    ll n,m;
    cin>>n>>m;
    cout<<n*m/__gcd(n,m)<<'\n';
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);
    int T;
    cin>>T;
    while(T--)solve();
}

B. Rakhsh's Revival

題意:給一個01串,每次操作可將長度為 \(k\) 的子串覆蓋為 1,問最少幾次操作可使串中不存在長度為 \(m\) 的全 0 子串。

遍歷,遇到長度為 \(m\) 的子串就從第 \(m\) 個 0 開始覆蓋。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

void solve(){
    int n,m,k;
    string s;
    cin>>n>>m>>k>>s;
    int len=0,res=0;
    for(int i=0;i<n;++i){
        if(s[i]=='0'){
            ++len;
            if(len==m){
                for(int j=0;j<k&&i+j<n;++j)s[i+j]='1';
                ++res,len=0;
            }
        }
        else len=0;
    }
    cout<<res<<'\n';
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);
    int T;
    cin>>T;
    while(T--)solve();
}

C. Trapped in the Witch's Labyrinth

題意:一個上下左右四箭頭的矩陣,某些位置待填,問最多有多少位置滿足從這個位置開始沿箭頭方向移動走不出矩陣。

BFS搜尋一定能走出去的位置,沒填的位置走不出去當且僅當它的四周全是能走出去的。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;

const int N=1005;
int n,m;
string a[N];
const int dx[4]={1,0,-1,0};
const int dy[4]={0,1,0,-1};
const char de[4]={'U','L','D','R'};
bool vis[N][N];
void solve(){
    cin>>n>>m;
    for(int i=0;i<n;++i)cin>>a[i];
    if(n==1&&m==1){
        cout<<"0\n";
        return;
    }
    for(int i=0;i<n;++i)
        for(int j=0;j<m;++j)
            vis[i][j]=0;
    queue<pii> q;
    for(int i=0;i<n;++i){
        if(a[i][0]=='L')q.push(pii(i,0));
        if(a[i][m-1]=='R')q.push(pii(i,m-1));
    }
    for(int i=0;i<m;++i){
        if(a[0][i]=='U')q.push(pii(0,i));
        if(a[n-1][i]=='D')q.push(pii(n-1,i));
    }
    while(!q.empty()){
        int x=q.front().first,y=q.front().second;
        q.pop();
        vis[x][y]=1;
        for(int i=0;i<4;++i){
            int xx=x+dx[i],yy=y+dy[i];
            if(xx<0||xx>=n||yy<0||yy>=m||a[xx][yy]=='?')continue;
            if(a[xx][yy]==de[i])q.push(pii(xx,yy));
        }
    }
    int ans=0;
    for(int i=0;i<n;++i)
        for(int j=0;j<m;++j){
            if(a[i][j]!='?'){
                if(!vis[i][j])++ans;
            }
            else{
                bool fl=0;
                for(int t=0;t<4;++t){
                    int ii=i+dx[t],jj=j+dy[t];
                    if(ii>=0&&ii<n&&jj>=0&&jj<m&&!vis[ii][jj]){fl=1;break;}
                }
                if(fl)++ans;
            }
        }
    cout<<ans<<'\n';
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);
    int T;
    cin>>T;
    while(T--)solve();
}

D. Darius' Wisdom

題意:\(n\) 堆石子,每堆石子數量不超過 2。每次只能交換兩堆石子數差 1 的石子,給出一種運算元不超過 \(n\) 的方案使所有石子從小到大排序。

先把所有的 1 歸位,然後用任意一個 1 把 0 和 2 歸位。具體見程式碼。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;

const int N=2e5+5;
int n,a[N],c[3];
vector<pii> ans;
vector<int> b[3][3];
int pos(int x){
    if(x>=1&&x<=c[0])return 0;
    else if(x>=c[0]+1&&x<=c[0]+c[1])return 1;
    else return 2;
}
void mov(int i1,int j1,int i2,int j2){
    int x=b[i1][j1].back(),y=b[i2][j2].back();
    ans.emplace_back(x,y);
    b[i1][j1].pop_back();
    b[i1-1][j1].push_back(x);
    b[i2][j2].pop_back();
    b[i2+1][j2].push_back(y);
}
void solve(){
    cin>>n;
    c[0]=c[1]=c[2]=0;
    for(int i=1;i<=n;++i)cin>>a[i],++c[a[i]];
    for(int i=0;i<3;++i)
        for(int j=0;j<3;++j)
            b[i][j].clear();
    for(int i=1;i<=n;++i)b[a[i]][pos(i)].push_back(i);
    ans.clear();
    while(b[0][1].size()||b[0][2].size()||b[1][0].size()||b[1][2].size()||b[2][0].size()||b[2][1].size()){
        int st=ans.size();
        while(b[2][0].size()&&b[1][2].size())mov(2,0,1,2);
        while(b[2][1].size()&&b[1][2].size())mov(2,1,1,2);
        while(b[1][0].size()&&b[0][2].size())mov(1,0,0,2);
        while(b[1][0].size()&&b[0][1].size())mov(1,0,0,1);
        if(ans.size()==st)break;
    }
    if(b[2][0].size()){
        int t=b[1][1].back(),m=b[2][0].size();
        ans.emplace_back(b[2][0][0],t);
        ans.emplace_back(b[2][0][0],b[0][2][0]);
        for(int i=1;i<m;++i){
            ans.emplace_back(b[2][0][i],b[0][2][i-1]);
            ans.emplace_back(b[2][0][i],b[0][2][i]);
        }
        ans.emplace_back(t,b[0][2][m-1]);
    }
    cout<<ans.size()<<'\n';
    for(auto&[x,y]:ans)cout<<x<<' '<<y<<'\n';
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);
    int T;
    cin>>T;
    while(T--)solve();
}

E. Permutations Harmony

題意:給 \(n,k\),構造 \(k\) 個不同的排列 \(p_1,\dots,p_k\),使得對所有的 \(j\)\(\sum_{i=1}^k p_{i,j}\) 相等。

\(n\) 為偶數,\(k\) 為奇數時,因為 \(n\nmid k\frac {n(n+1)}2\),所以無解;

\(k=1,k=n!-1,k>n!\) 時,無解;

其他情況均有解,分 \(k\) 為奇數和偶數討論。

  • \(k\) 為偶數時:12345 54321 12354 54312……從小到大列舉排列配上 \(n+1\) 減每一項的排列即可。

  • \(k\) 為奇數時:我們先構造出一組 \(k=3\) 的。第一個排列從小到大,第二個排列奇數項從 \(\frac{n+1}2\) 開始遞減、偶數項從 \(n\) 開始遞減。以 \(n=7\) 為例:1234567 4736251 7362514。剩下的和 \(k\) 為偶數一樣,碰到重複的跳過即可。這樣恰好可以把 \(k\)\(3\)\(n!-3\) 的所有情況都構造出來。

注意特判 \(n=k=1\)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;

const int N=2e5+5;
const int fac[9]={1,1,2,6,24,120,720,5040,40320};
int n,k,p[N],q[N],r[N];
void solve(){
    cin>>n>>k;
    if(k==1){
        if(n==1)cout<<"YES\n1\n";
        else cout<<"NO\n";
    }
    else if(n<=8&&k>fac[n])cout<<"NO\n";
    else if(!(n&1)&&(k&1))cout<<"NO\n";
    else if(n<=8&&k==fac[n]-1)cout<<"NO\n";
    else{
        cout<<"YES\n";
        for(int i=1;i<=n;++i)p[i]=i;
        if(!(k&1)){
            for(int i=1;i<=k;i+=2){
                for(int i=1;i<=n;++i)cout<<p[i]<<' ';
                cout<<'\n';
                for(int i=1;i<=n;++i)cout<<n-p[i]+1<<' ';
                cout<<'\n';
                next_permutation(p+1,p+n+1);
            }
        }
        else{
            for(int i=1;i<=n/2;++i)q[i*2-1]=n/2+2-i,q[i*2]=n+1-i;
            q[n]=1;
            for(int i=1;i<=n/2;++i)r[i*2]=n/2+1-i,r[i*2+1]=n-i;
            r[1]=n;
            for(int i=1;i<=n;++i)cout<<p[i]<<' ';
            cout<<'\n';
            for(int i=1;i<=n;++i)cout<<q[i]<<' ';
            cout<<'\n';
            for(int i=1;i<=n;++i)cout<<r[i]<<' ';
            cout<<'\n';
            for(int i=4;i<=k;i+=2){
                bool fl1=1,fl2=1,fl3=1,fl4=1,fl5=1,fl6=1;
                for(int i=1;i<=n;++i){
                    if(p[i]!=i)fl1=0;
                    if(p[i]!=q[i])fl2=0;
                    if(p[i]!=r[1])fl3=0;
                    if(n-p[i]+1!=i)fl4=0;
                    if(n-p[i]+1!=q[i])fl5=0;
                    if(n-p[i]+1!=r[i])fl6=0;
                }
                if(!fl1&&!fl2&&!fl3&&!fl4&&!fl5&&!fl6){
                    for(int i=1;i<=n;++i)cout<<p[i]<<' ';
                    cout<<'\n';
                    for(int i=1;i<=n;++i)cout<<n-p[i]+1<<' ';
                    cout<<'\n';
                }
                else i-=2;
                next_permutation(p+1,p+n+1);
            }
        }
    }
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0);
    int T;
    cin>>T;
    while(T--)solve();
}

相關文章