B. Obtaining the String

题意:给一个a串和b串,问经过多少次相邻的交换,可以将a串转为b串

思路:暴力枚举,当我们枚举到a的后面某个位置有,就把他交换过来

代码:

#include<bits/stdc++.h>
using namespace std;
int const N=1e4+5;
#define int long long

void solve(){
    int n;
    cin>>n;
    string a;
    string b;
    cin>>a>>b;
    vector<int >ans;
    for (int i = 0; i <n ; ++i) {
        if(a[i]!=b[i]){
            int g=a.find(b[i],i);
            if(g>a.size()){
                cout<<"-1\n";
                return;
            }
            for (int j = g; j >i ; --j) {
                ans.push_back(j);
                swap(a[j],a[j-1]);
            }
        }
    }
    cout<<ans.size()<<endl;
    for (auto i:ans) {
        cout<<i <<' ';
    }

}
signed main(){
    ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    int t=1;
    while(t--){
        solve();
    }

}

C. Songs Compression

题意:懂得都懂

思路:先取最大的,加到s中,然后根据差值的大小排序,最大的往前放, 然后再判断,要注意顺序,不然就被卡住,我用的是二分

代码:

#include<bits/stdc++.h>
using namespace std;
#define  int long long
void solve(){
    int n,m;
    cin>>n>>m;
    int s=0;
    vector<int >ans;
    for (int i = 0; i <n ; ++i) {
        int x,y;
        cin>>x>>y;
        s+=x;
        ans.push_back(x-y);
    }
    sort(ans.begin(),ans.end(),greater<int>());
    int res=-1;
    auto check=[&](int mid){
        int p=s;
        for (int i = 0; i <mid ; ++i) {
            p-=ans[i];
        }
        return p<=m;

    };
    int l=0,r=n;
    while(l<=r){
        int mid=l+r>>1;
        if(check(mid)){
            r=mid-1;
            res=mid;
        }
        else{
            l=mid+1;
        }
    }
    cout<<res<<endl;

}
signed main(){
    int t=1;

    while(t--){
        solve();
    }
}

D. Walking Between Houses

题意:长度为n的路,从一开始跳,每次跳的长度小于n,问k次能否使跳的长度为s,如果可以,输出跳跃顺序

思路:当(n-1)* k<s时,不可以,当k>s时,也不可以,我们可以选择反复横跳,每次跳跃的距离首先我们先平分一下为s/k,然后我们把余数,前几次的跳跃我们每一次都加1,然后当加完的时候,再重复那个操作

代码:

#include<bits/stdc++.h>
using namespace std;
#define  int long long
void solve(){
    int n,k,s;
    cin>>n>>k>>s;
    int g=n-1;
    if(k>s){
        cout<<"NO\n";
        return;
    }
    if(g*k>=s){
        cout<<"YES\n";
    }
    else{
        cout<<"NO\n";
        return;
    }
    vector<int>ans;
    int p=s%k;
    int ks=s/k;
    int ls=1;
    int vis=0;
    if(p==0){
        for (int i = 0; i <k ; ++i) {
            if(i%2==0){
                cout<<1+ks<<' ';
            }
            else{
                cout<<1<<' ';
            }
        }
        return;
    }
    for (int i = 0; i <k ; ++i) {
        p--;
        if(p>=0){
          if(ls==1){
              cout<<1+ks+1<<' ';
              ls=1+ks+1;
          }
          else{
              cout<<1<<' ';
              ls=1;
          }
        }
        else{
            if(vis==0){
                vis=1;
                if(ls==2+ks){
                    cout<<2<<' ';
                    ls=2;
                }
                else{
                    cout<<1+ks<<' ';
                    ls=1+ks;
                }
            }
            else{
                if(ls==2){
                    cout<<2+ks<<' ';
                    ls=2+ks;
                }
                else if(ls==2+ks){
                    cout<<2<<' ';
                    ls=2;
                }
                else if(ls==1+ks){
                    cout<<1<<' ';
                    ls=1;
                }
                else {
                    cout<<1+ks<<' ';
                    ls=1+ks;
                }

            }

        }
    }
}
signed main(){
    int t=1;

    while(t--){
        solve();
    }
}

E1. Stars Drawing (Easy Edition)

题意:如图这种图像算做一个星星,如果所有的 * 都是在星星之中,那么输出大小和星星中点的坐标

思路:E1数据较小,因此我们可以枚举每一个点,然后再枚举长度,看能够多大,然后标记一下合法的,最后判断是否有不合法的 *

代码:

#include<bits/stdc++.h>
using namespace std;
#define  int long long
struct node{
    int x, y, s;
};
void solve(){
    int n,m;
    cin>>n>>m;
    string s[n+1];
    for (int i = 1; i <=n ; ++i) {
        cin>>s[i];
        s[i]=" "+s[i];
    }
    vector<node>ans;
    vector<vector<bool>>q(n+1,vector<bool>(m+1, false));
    for (int i = 1; i <=n ; ++i) {
        for (int j = 1; j <=m ; ++j) {
            int l=0,x=i,y= j;
            if(s[i][j]=='*'){
                for (int len = 1; i-len >=1&&i+len<=n&&j-len>=1 &&j+len<=m; ++len) {
                    if(s[i+len][j]=='*'&&s[i-len][j]=='*'&&s[i][j+len]=='*'&&s[i][j-len]=='*'){
                     l=len;
                        q[i][j]=true;
                        q[i+len][j]=true;
                        q[i-len][j]=true;
                        q[i][j+len]=true;
                        q[i][j-len]=true;
                    }
                    else break;

                }
            }
            if(l){
                node t;
                t.x=i,t.y=j,t.s=l;
                ans.push_back(t);
            }
        }
    }
    for (int i = 1; i <=n ; ++i) {
        for (int j = 1; j <=m ; ++j) {
            if(s[i][j]=='*'){
                if(q[i][j]==false){
                    cout<<"-1\n";
                    return;
                }
            }
        }
    }
    cout<<ans.size()<<endl;
        for (auto i:ans) {
            cout<<i.x<<' '<<i.y<<' '<<i.s<<endl;
    }
}
signed main(){
    int t=1;

    while(t--){
        solve();
    }
}

E2. Stars Drawing (Hard Edition)

题意:数据范围变大

思路:我们时间复杂度若还是n m n,那么就会tle,我们考虑优化,维护一个点的上下左右各能够延申多少,这个预处理O(mn)即可处理,然后我们对每一个 的上下左右数组取最小,如果是大于1,则可以形成星星,然后我们对上左和上的方向的星星的第一个位置标记为1,在右和下方向的最后一个位置的下一位标记为-1。最后差分求一下每一个 的标记值,如果有 * 的标记值不是0,那么输出-1

代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
#define  int long long
struct node{
    int x, y, s;
};

const int maxn = 1010;
char s[maxn][maxn];
int l[maxn][maxn],r[maxn][maxn],up[maxn][maxn],down[maxn][maxn];
int jdugex[maxn][maxn],jdugey[maxn][maxn];

void solve(){
    int n,m;
    cin>>n>>m;
    for (int i = 1; i <=n ; ++i) {
        for (int j = 1; j <=m ; ++j) {
            cin>>s[i][j];
        }
    }
//    vector<node>ans;
//    vector<vector<bool>>q(n+1,vector<bool>(m+1, false));
//    vector<vector<int>>l,r,up,down,jdugex,jdugey(n+1,vector<int>(m+1, 0));
    for (int i = 1; i <=n ; ++i) {
        for (int j = 1; j <=m ; ++j) {
            if(s[i][j]=='*'){
                l[i][j]=(l[i] [j-1]+1);
                up[i][j]=up[i-1][j]+1;
            }
        }
    }
    for (int i = n; i >=1 ; --i) {
        for (int j = m; j >=1 ; --j) {
            if(s[i][j]=='*'){
                r[i][j]=r[i][j+1]+1;
                down[i][j]=down[i+1][j]+1;
            }
        }
    }
    vector<node>ans;
    for (int i = 1; i <=n ; ++i) {
        for (int j = 1; j <=m ; ++j) {
            int mi=1000000;
            if(s[i][j]=='*'){
                mi=min(mi,min(r[i][j],down[i][j]));
                mi=min(mi,min(l[i][j],up[i][j]));
                if(mi>1){
                    ans.push_back({i,j,mi-1});
                    jdugex[i-mi+1][j]++;
                    jdugex[i+mi][j]--;
                    jdugey[i][j-mi+1]++;
                    jdugey[i][j+mi]--;

                }
            }
        }
    }
    for (int i = 1; i <=n ; ++i) {
        for (int j = 1; j <=m ; ++j) {
            jdugex[i][j]+=jdugex[i-1][j];
            jdugey[i][j]+=jdugey[i][j-1];
        }
    }

    for (int i = 1; i <=n ; ++i) {
        for (int j = 1; j <=m ; ++j) {
            if(jdugex[i][j]==0&&jdugey[i][j]==0&&s[i][j]=='*'){
//                cout<<i<<' '<<j;
                cout<<"-1";
                return;
            }
        }
    }

    cout<<ans.size()<<'\n';
    for (auto i:ans) {
        cout<<i.x<<' '<<i.y<<' '<<i.s<<'\n';
    }

}
signed main(){
    ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int t=1;

    while(t--){
        solve();
    }
}
posted on 2023-07-24 18:49  IR101  阅读(7)  评论(0编辑  收藏  举报  来源