2019暑假牛客第7场A-string-最小表示法+暴力

题面:
在这里插入图片描述
在这里插入图片描述思路:
最小表示法,每次贪心选择最长的串判断它是否满足条件。
哦调了一下午,结果是板子的问题。
之前的板子是只有最小表示法,这个可以求两种,一种封装,到时候直接调用即可。

#include<bits/stdc++.h>
#define per(i,a,b) for(int i = (a);i <= (b);++i)
#define rep(i,a,b) for(int i = (a);i >= (b);--i)
using namespace std;
const int maxn = 2e2 + 10;
char s[maxn];
struct node{
	int l,r;
};

int get_max_min(string& s,int flag){
    int len = s.length();
    int i = 0, j = 1, k = 0, t;
    while(i < len && j < len && k < len) {
        t = s[(j + k) % len] - s[(i + k) % len];
        if(t == 0){
        	k++;
        }else{
            if(flag == 1){//最大表示法
                if(t >= 0){
                	// i += k + 1;
                	i = max(i+k+1,j+1);
                }else{
                	// j += k + 1;
                	j = max(j+k+1,i+1);
                } 
            }else{//最小表示法
                if(t >= 0){
                	// if(j +k+1 > i){
                	// 	j += k + 1;
                	// }else{
                	// 	j = i+1;
                	// }
                	j = max(j+k+1,i+1);
                }else{
                	// if(i+k+1 > j){
                	// 	i += k + 1;
                	// }else{
                	// 	i = j+1;
                	// }
                	i = max(i+k+1,j+1);
                } 
            }
            if(i == j){
            	++j;
            }
            k = 0;
        }
    }
    return min(i, j);
}

int main(){
	// std::ios::sync_with_stdio(false);
	// cin.tie(0);cout.tie(0);
	int T = 0;
	scanf("%d",&T);
	while(T--){
		scanf("%s",s);
		int len = strlen(s);
		int fir = 0,las = 0;
		vector<node> ans;
		while(las <= len-1){
			rep(i,len-1,fir){
				string tmp = "";
				per(j,fir,i){
					tmp += s[j];
				}
				int res = get_max_min(tmp,0);
				if(res == 0){
					las = i;
					break;
				}
			}
			ans.push_back(node{fir,las});
			fir = las + 1;
			las=  fir;
		}
		int si = ans.size();
		per(i,0,si-1){
			per(j,ans[i].l,ans[i].r){
				printf("%c",s[j]);
			}
			printf(" ");
		}
		printf("\n");
	}
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值