HDU 4162 Shape Number

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4162

题意:

求给定字符的一阶差分链的最小表示。

题解:

先求一阶差分链,再求一阶差分链的最小表示法。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 3e5 + 10;

char s1[maxn],s2[maxn];

int solve(char *s) {
    int i = 0, j = 1, k = 0,len=strlen(s);
    while (i < len&&j < len&&k<len) {
        int t = s[(i + k) % len] - s[(j + k) % len];
        if (!t) k++;
        else {
            if (t > 0) i = i + k + 1;
            else j = j + k + 1;
            if (i == j) j++;
            k = 0;
        }
    }
    return i < j ? i : j;
}

int main() {
    while (scanf("%s", s1) == 1) {
        int len = strlen(s1);
        for (int i = 0; i < len; i++) {
            s2[i] = (s1[(i + 1) % len] - s1[i] + 8) % 8 + ‘0‘;
        }
        s2[len] = ‘\0‘;
        //cout << s2 << endl;
        int pos = solve(s2);
        for (int i = 0; i < len; i++) {
            printf("%c", s2[(pos + i) % len]);
        }
        printf("\n");
    }
    return 0;
}
时间: 2024-11-02 12:01:13

HDU 4162 Shape Number的相关文章

HDU 4162 Shape Number(字符串,最小表示法)

HDU 4162 题意: 给一个数字串(length <= 300,000),数字由0~7构成,求出一阶差分码,然后输出与该差分码循环同构的最小字典序差分码. 思路: 第一步是将差分码求出:s[i] = (s[i] - s[i+1] + 8) % 8; 第二步是求出最小字典序的循环同构差分码,我之前没注意到字符串规模..直接用set做,MLE+TLE... 正确的方式应该是一种O(n)的解法,即最小表示法.//关于最小表示法的证明与详述请参考最小表示法:) 最小表示法算法: 初始时,i=0,j=

HDU 4162 Shape Number 最小表示法

Shape Number Time Limit: 24000/12000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 981    Accepted Submission(s): 471 Problem Description In computer vision, a chain code is a sequence of numbers representing direc

HDU 4162 Shape Number (最小表示法)

题意:给你一串n个数,求出循环来看一阶差的最小字典序:数字串看成一个顺时针的环,从某一点开始顺时针循环整个环,保证字典序最小就是答案 例如给你 2 1 3 就会得到(1-2+8 注意题意负数需要加8) (3-1) (2-3+8)-> 7 2 7 答案就是2 7 7. 典型的最小表示法.线性时间内求出最小字典序. 首先复制一遍数字串在原串后面,这样从原串任意位置开始向再后n个位置就是答案.接着双指针维护,直接双指针暴力比较数字串,当出现不同数字时,就把字典序大的那个指针向后移动尽量多的位置这样可以

HDU 4937 Lucky Number 搜索

题意: 给你一个数,求在多少种不同的进制下这个数每一位都是3.4.5.6中的一个. 思路: 搜索.枚举这个数在任意进制下的表示,判断是否合法.当数字只有3.4.5.6时,必定有无穷种. 因为数字太大,所以直接枚举必定会超时. 下面有两种剪枝的方法: 1. 先枚举最后一位的情况. 假设数字n在base进制下表示为 a[n]...a[0],即 n = a[0] + a[1]*base^1 + ... + a[n]*base^n. 则 n - a[0] = a[1]*base^1 + ... + a[

hdu 4937 Lucky Number ( 进制转换+枚举 )

题意: 有一个数n,问有多少个进制x(基数)使得n转换为x进制后的数字中只有3.4.5.6四个数. 算法: 对于只有一位数的情况,显然3.4.5.6都应该输出-1. 如果有2位数,假设这2位中高位为a,低位为b,进制为base,则 n = a * base + b,解一元一次方程即可. 如果有3位数,假设这3为从高到低分别为a.b.c,进制为base,则 n = a * base * base + b * base + c,即一元二次方程即可. 如果位数>= 4,可以暴力枚举进制数.base>

hdu 2665 Kth number(划分树)

Kth number Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4602 Accepted Submission(s): 1468 Problem Description Give you a sequence and ask you the kth big number of a inteval. Input The first l

hdu 3006 The Number of set(思维+壮压DP)

The Number of set Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1056    Accepted Submission(s): 655 Problem Description Given you n sets.All positive integers in sets are not less than 1 and

hdu 5787 K-wolf Number 数位dp

数位DP 神模板 详解 为了方便自己参看,我把代码复制过来吧 // pos = 当前处理的位置(一般从高位到低位) // pre = 上一个位的数字(更高的那一位) // status = 要达到的状态,如果为1则可以认为找到了答案,到时候用来返回, // 给计数器+1. // limit = 是否受限,也即当前处理这位能否随便取值.如567,当前处理6这位, // 如果前面取的是4,则当前这位可以取0-9.如果前面取的5,那么当前 // 这位就不能随便取,不然会超出这个数的范围,所以如果前面取

枚举 + 进制转换 --- hdu 4937 Lucky Number

Lucky Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 294    Accepted Submission(s): 49 Problem Description “Ladies and Gentlemen, It’s show time! ” “A thief is a creative artist who ta