【模拟\搜索\STL】谁是下一个

来源:互联网 发布:软件测试技能 编辑:程序博客网 时间:2024/05/02 00:27

第1题:谁是下一个

 

【题目描述】

在那遥远的地方有座监狱叫做MSHS。这座监狱每天都要枪毙一个犯人。按犯人的编号从小到大一个一个枪毙。犯人的号码是由几个1到9的阿拉伯数字以及若干个0组成的。1到9的数字在所有犯人的号码里出现次数都相同。0则不一定,不过0不会出现在号码的第一位。

两个号码的比较采取这样的方式。长度长的号码排后面,如果长度相等那么字典序大的号码排后面。

现在给出今天枪毙的犯人的号码,要你求出明天枪毙犯人的号码。

 

【输入格式】

第一行一个正整数T,代表有T组数据。

接下来T行,每行一个字符串,为今天枪毙犯人的号码。保证只含0-9的字符并且首位不为0。注意这T组数据是相互分离的,即不一定采取同样的数字进行编码。

 

【输出格式】

输出T行,每行一个字符串,顺次为每组数据的明天被枪毙犯人的号码。

 

【数据范围】

对于30分的数据,每个号码长度小于等于6位。

对于100分的数据,号码长度小于等于20,T小于等于50。

 


【输入样例】

3

115

1051

6233

 

【输出样例】

151

1105

6323




我以为我是机房里对C++掌握最好的,结果暴露出STL是一大块问题。

这道题应该用next_permutation,这个可以直接生成下一个排列。

但是需要特判,如果说产生了前导零,处理方法是,将所有零放到next_permutation产生的排列的第一个非零数字后面。这样必定最小,且大于原串。


如果不用next_permutation很麻烦。同样要特判。然后注意到有前几位相等,在某一位新串大于原串,这之后就没有要求。所以我们便按照这个方案来搜索,用一个greater标志来记录是否已经有一位新串大于了原串。


#include <cstdio>#include <string>#include <cstring>#include <algorithm>using std::sort;long _n;char num[30];long ans[30];char _num[30];long used[30];long start[30];bool ok = false;long n = 0;bool dfs(long u,bool greater){if (u == _n+1){if (ok){for (long i=1;i<_n+1;i++){printf("%ld",ans[i]);}return true;}else{ok = true;return false;}}long ll = 0;if (greater)ll = 1;elsell = start[_num[u]];for (long i=ll;i<n+1;i++){if (used[num[i]]>-1 && (u>1||num[i]>0)){used[num[i]] --;ans[u] = num[i];if (num[i] > _num[u]){if (dfs(u+1,true))return true;}else{if (dfs(u+1,greater||false))return true;}used[num[i]] ++;}}return false;}int main(){freopen("next.in","r",stdin);freopen("next.out","w",stdout);long T;scanf("%ld",&T);while (T --){memset(start,0,sizeof start);memset(_num,0,sizeof _num);memset(num,0,sizeof num);memset(used,0,sizeof used);ok = false;n = 0;scanf("%s",_num+1);while (_num[++n]){num[n]=_num[n]=_num[n]-'0';}n --;bool flag = true;for (long i=2;i<n+1;i++)if (num[i] > num[i-1])flag = false;if (flag){sort(num+1,num+1+n);if (num[1] != 0){printf("%ld0",num[1]);for (long i=2;i<n+1;i++)printf("%ld",num[i]);printf("\n");}else{long zero = 0;while (zero<n && num[++zero]==0);zero--;printf("%ld",num[zero+1]);for (long i=1;i<zero+2;i++)printf("0");for (long i=zero+2;i<n+1;i++)printf("%ld",num[i]);printf("\n");}continue;}sort(num+1,num+1+n);long j = 1;for (long i=2;i<n+1;i++){if (num[i] == num[j])used[num[i]] ++;elsenum[++j] = num[i];}_n = n;n = j;for (long i=1;i<n+1;i++)if (!start[num[i]])start[num[i]] = i;dfs(1,false);printf("\n");}return 0;}

#include <cstdio>#include <string>#include <cstring>#include <algorithm>using std::sort;using std::next_permutation;char num[60];char _num[60];int main(){freopen("next.in","r",stdin);freopen("next.out","w",stdout);long T;scanf("%ld",&T);while (T --){long n = 0;scanf("%s",num+1);while (num[++n]){_num[n]=num[n]=num[n]-'0';} n --;next_permutation(num+1,num+1+n);if (strcmp(num+1,_num+1)==0){printf("%ld0",num[1]);for (long i=2;i<n+1;i++)printf("%ld",num[i]);printf("\n");continue;}if (num[1] == 0){long zero=0;while (zero<n&&num[++zero]==0);zero--;printf("%ld",num[zero+1]);for (long i=1;i<zero+2;i++)printf("0");for (long i=zero+2;i<n+1;i++)printf("%ld",num[i]);printf("\n");continue;}for (long i=1;i<n+1;i++)printf("%ld",num[i]);printf("\n");}return 0;}


原创粉丝点击