2019牛客多校第七场A题

A-String_2019牛客暑期多校训练营(第七场)

https://ac.nowcoder.com/acm/contest/887/A

题意:将字符串分割为尽量少的子字符串,每一个子字符串都是本身所有循环排列的字典序最小值
开场第一眼看的A题 觉得能做,一开始的想法是遇见先0后1就输出完1然后空格,后来发现题目的0101就不对
后来想到做每一个1的前导0的数量,当前导0数量非递减排列的时候,必然要分割,当相邻两端前导0数量相等我们判断1的数量,1的数量非递增就可以连着,否则就分开,如此一来,样例和能想到的数据都能过了,贴一个wa码

#include<cstdio>
#include <algorithm>
#include <iostream>
#include <memory.h>
#include <queue>

#define rep(i, n) for(int i=0;i<n;i++)
#define per(i, n) for(int i=n;i>=1;i--)
#define pb(x) push_back(x)
#define clint(x, n) memset(x,n,sizeof(x))
typedef long long ll;
const int maxn = 25;
const ll inf = 99999999;
using namespace std;
int dirx[] = {1, 0, -1, 0, 0, 0};
int diry[] = {0, 1, 0, -1, 0, 0};
int dirz[] = {0, 0, 0, 0, 1, -1};
int px, py, pz;
int m, n, T, t;
char ma[30][30][30];
int vis[30][30][30];
int ans;
int ex, ey, ez;
char ss[10];
string str;

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        cin >> str;
        int len = str.size();
        int ff[1000];
        int mark[300];
        clint(mark, -1);
        clint(ff, 0);
        int cnt0 = 0, cnt1 = 0;
        int x1, x2;
        int i = 0;
        for (i = 0; i < len; i++) {
            if (str[i] == '1') cout << str[i], mark[i] = 0;
            else break;
        }
        if(str[0]=='1') cout << ' ';
        for (int j = i; j < len; j++) {
            if (str[j] == '1') {
                for (int k = j - 1; k >= 0; k--) {
                    if (str[k] == '1' || k == 0) {
                        if (k == 0 && str[0] == '0')
                            cnt0++;
                        mark[j] = cnt0;
                        //cout<<"test:"<<j<<' '<<mark[j]<<endl;
                        cnt1++;
                        cnt0 = 0;
                        break;
                    } else {
                        cnt0++;
                    }
                }
            }
        }
        rep(j, len) {
            //cout << mark[j] << ' ';
            if (mark[j] > 0) {
                for (int k = j - 1; k >= 0; k--) {
                    if (mark[k] < mark[j]&&mark[k]>0) {
                        for (int o = k; o <= j; o++) {
                            if (mark[o] == -1) {
                                ff[o - 1] = 1;
                                break;
                            }
                        }
                    } else if (mark[k]==mark[j]&&mark[k]>0) {
                        x1 = 0, x2 = 0;
                        for (int o = k; o < len; o++) {
                            if (mark[o] == -1) break;
                            x1++;
                        }
                        for (int o = j; o < len; o++) {
                            if (mark[o] == -1) break;
                            x2++;
                        }
                        if (x2 < x1)
                            for (int o = k; o <= j; o++) {
                                if (mark[o] == -1) {
                                    ff[o - 1] = 1;
                                    break;
                                }
                            }
                    }
                }
            }
        }
        if(str[len-1]=='0'){
            for(int j=len;j>=0;j--){
                if(mark[j]>=0) {
                    ff[j]=1;
                    break;
                }
            }
        }
//        rep(j,len) cout<<mark[j]<<' ';
//        cout<<endl;
        for (int j = i; j < len; j++) {
            cout << str[j];
            if (ff[j]) cout << ' ';

        }
        cout << endl;
    }
    return 0;
}

后来我看题解居然直接暴力????我都没看过这种题能暴力,不过。。。数据长度200.不暴力都对不起自己啊。。我无语了,贴一个补题ac码:

#include<cstdio>
#include <algorithm>
#include <iostream>
#include <memory.h>
#include <queue>

#define rep(i, n) for(int i=0;i<n;i++)
#define per(i, n) for(int i=n;i>=1;i--)
#define pb(x) push_back(x)
#define clint(x, n) memset(x,n,sizeof(x))
typedef long long ll;
const int maxn = 25;
const ll inf = 99999999;
using namespace std;
int dirx[] = {1, 0, -1, 0, 0, 0};
int diry[] = {0, 1, 0, -1, 0, 0};
int dirz[] = {0, 0, 0, 0, 1, -1};
int px, py, pz;
int m, n, T, t;
char ma[30][30][30];
int vis[30][30][30];
int ans;
int ex, ey, ez;
char ss[10];
string str;
bool check(string s){                                 //判断当前字符串是否自身循环内字典序最小
    int len=s.length();
    for(int i=1;i<len;i++)                            //枚举循环情况
        for(int j=0;j<len;j++){                       //枚举s中字符 比较字典序
            if(s[j]<s[(i+j)%len]) break;              //如若当前位小于 则无需再次比较 一定小于
            if(s[j]>s[(i+j)%len]) return false;       // 如果当前位大于 说明不是字典序最小
        }
    return true;
}

int main()
{
    int t;
    cin>>t;
    while(t--){
        string s;
        cin>>s;
        int len=s.length();
        int i=0;
        while(i<len){
            for(int j=len-i;j>=0;j--){           //暴力枚举当前01串长度
                if(check(s.substr(i,j))){        //判断 从i位置开始到j的01串 是否最小        复制字符串-> substr(开始位置,长度)
                    cout<<s.substr(i,j);         //输出
                    i+=j;                        //将i移至当前字符串之后一位
                    if(i<len) cout<<" ";         //如果不是最后一串01串 加上空格
                    break;                       //已经找到字符串 跳出本次循环
                }
            }
        }
        cout<<endl;
    }
    return 0;
}
全部评论

相关推荐

牛客5655:其他公司的面试(事)吗
点赞 评论 收藏
分享
拒绝无效加班的小师弟很中意你:求职意向没有,年龄、课程冗余信息可以删掉,需要提升项目经历。排版需要修改。
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务