• [模板][字符串] 最小表示


    字符串最小表示:

    给定一循环字符串,求出位置k使得从k位置开始的字符串字典序最小


    解法 : 设双指针i, j 比较 s[i] 与 s[j] 的关系

    若s[i] == s[j]  则以i,j开头的两字符的大小关系目前是相同的

    直接向后, 找到第一个不同点i,j  若有s[i + k] > s[j + k], 则必有以i - i + k开头的字符串非最小 废话

    反之亦然 这一大部分可以直接跳过 

    直到 i 或 j 跑出n范围 此时较小的开始点即为最小表示


    例题:

    http://poj.org/problem?id=1509


    代码

    int getmin(string s)
    {
        int n = s.length();
        int i = 0, j = 1, k = 0, t;
        while(i < n && j < n && k < n)
        {
            t = s[(i + k) % n] - s[(j + k) % n];
            if (!t) k++;
            else
    		{
                if (t > 0) i += k + 1;
                else j += k + 1;
                if (i == j) j++;
                k = 0;
            }
        }
        return i < j ? i : j;
    }
    /*
    	Zeolim - An AC a day keeps the bug away
    */
    
    //pragma GCC optimize(2)
    #include <cstdio>
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    #include <cctype>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <stack>
    #include <queue>
    #include <set>
    #include <sstream>
    #include <map>
    #include <ctime>
    #include <vector>
    #include <fstream>
    #include <list>
    #include <iomanip>
    #include <numeric>
    using namespace std;
    typedef long long ll;
    
    const int MAXN = 1e6 + 10;
    
    char s[MAXN] = " ";
    
    int minstr(int n)
    {
    	int i = 0, j = 1, k = 0;
    	
    	while(i < n && j < n)
    	{
    		for(k = 0; k < n; k++)
    			if(s[i + k] != s[j + k])
    				break;
    				
    		if(k == n)
    			break;
    			
    		if(s[(i + k) % n] > s[(j + k) % n])
    			i += (k + 1);
    		else
    			j += (k + 1);
    			
    		if(i == j)
    			++j;
    	}
    	
    	return i < j ? i : j;
    }
    
    int main()
    {
        //ios::sync_with_stdio(false);
        //cin.tie(0);     cout.tie(0);
        //freopen("D://test.in", "r", stdin);
        //freopen("D://test.out", "w", stdout);
        
        int n;
    
        cin>>n;
    
        while(n--)
        {
        	cin>>s;
        	
        	int len = strlen(s);
        	
        	int ans = minstr(len) + 1;
        	
        	cout<<ans<<'
    ';
        }
    
        return 0;
    }
  • 相关阅读:
    (8)route命令(每周一个linux命令系列)
    linux下怎么找到某些命令出自于哪个包
    centos网卡配置详解
    linux下查看系统版本
    (7)awk命令(每周一个linux命令系列)
    centos增加环境变量
    mysql用户操作、权限分配、远程登录设置
    (6)sudo命令详解(每周一个linux命令系列)
    最近的linux工作记录
    (5)ps详解 (每周一个linux命令系列)
  • 原文地址:https://www.cnblogs.com/zeolim/p/12270387.html
Copyright © 2020-2023  润新知