题解数字交换游戏

Posted kcn999

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解数字交换游戏相关的知识,希望对你有一定的参考价值。

题目描述

  桐桐已经是中学生了。她喜欢研究数字,觉得最漂亮的数就是整数了。

  一次,桐桐写下一个整数(无前导0),她想研究下面这个游戏:每次取其中两位交换,会得到一个新的整数——但不能有前导0出现,即第一位不能变成0.这样连续做m次,最后能得到的最大整数是多少?

 

输入格式

  一行,两个整数N(1≤N≤1000000)和m(1≤m≤10)。

 

输出格式

  一行,一个整数,为桐桐变化后的最大数,如果不能变换则输出-1。

 

输入样例一

16375 1

 

输出样例一

76315

 

输入样例二

432 1
 

输出样例二

423

 

输入样例三

90 4

 

输出样例三

-1

 

题解

  一个比较简单的贪心策略。先看当前的数从最高位到最低位是否不上升,如果不上升就换相同的数字,否则换最后两个数字。

  存在上升子序列的情况就有点麻烦了。

  我们从最高位开始枚举,设当前为的数字为$a[i]$,那我们需要在$(i,len]$中找满足$a[p]>a[i]$的最大的$a[p]$,更换这两个数字即可。

  但是,如果有多个$a[p]$怎么办?我们设$(i,len]$中比$a[i]$大的$a[j]$的数量为$cnt$,和当前枚举到的$a[p]$的数量为$same$。

  假设当前枚举到一个$a[j]$与$a[p]$相等,我们容易想到,如果$same>m$,我们就不需要更新$p$。否则,如果$cnt-same=0$或$cnt-same geqslant same$,那我们也不需要更新$p$,否则更新$p=j$。

技术图片
#include <iostream>
#include <cstring>

using namespace std;

char a[10];
int len, m;

int main()
{
    cin >> a + 1 >> m;
    len = strlen(a + 1);
    if(len == 1 || len == 2 && a[2] == 0) return cout << -1, 0;
    int f, p, cnt, same;
    ++m;
    while(--m)
    {
        f = 1;
        for(register int i = 1; i < len; ++i)
        {
            p = cnt = same = 0;
            for(register int j = i + 1; j <= len; ++j)
            {
                if(a[j] <= a[i]) continue;
                ++cnt;
                if(a[j] > a[p]) p = j, same = 1;
                else if(a[j] == a[p])
                {
                    ++same;
                    if(same > m) continue;
                    if(cnt == same || cnt - same >= same) continue;
                    p = j;
                }
            }
            if(!p) continue;
            f = 0;
            swap(a[i], a[p]);
            break;
        }
        if(f)
        {
            for(register int i = 1; i < len; ++i)
            {
                if(a[i] == a[i + 1]) 
                {
                    f = 0;
                    break;
                }
            }
            if(f) swap(a[len - 1], a[len]);
        }
        // cout << a + 1 << "
";
    }
    cout << a + 1;
    return 0;
}
参考程序

 

以上是关于题解数字交换游戏的主要内容,如果未能解决你的问题,请参考以下文章

[HG]diamond 题解

[NOIP2012]国王游戏 题解

猜数字小游戏

UVa340 Master-Mind Hints 猜数字游戏的提示 题解

P1132 数字生成游戏 结题报告

[题解]Mayan游戏