【题解】数字交换游戏

题目描述

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

  一次,桐桐写下一个整数(无前导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 << "\n";
    }
    cout << a + 1;
    return 0;
}

参考程序

原文地址:https://www.cnblogs.com/kcn999/p/10742437.html

时间: 2024-10-12 04:20:17

【题解】数字交换游戏的相关文章

[题解]Mayan游戏

Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个7行5列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他方块之上.游戏通关是指在规定的步数内消除所有的方块,消除方块的规则如下: 1.每步移动可以且仅可以沿横向(即向左或向右)拖动某一方块一格:当拖动这一方块时,如果拖动后到达的位置(以下称目标位置)也有方块,那么这两个方块将交换位置(参见图6到图7):如果目标位置上没有方块,那么被拖动的方块将从原来的竖列中抽出,并从目标位置上掉落(直到不悬空,参

[题解] [JSOI2013] 游戏中的学问

题面 题解 这个数据范围, 直接 DP 一下就完了 看是这个人新开一个圈还是加到别的圈里去 注意, 新开一个圈最少需要三个人 设 \(f[i][j]\) 为前 \(i\) 个人组成 \(j\) 个圈的方案数 \[ f[i][j] = \begin{cases} f[i - 1][j] * (i - 1)\f[i - 3][j - 1] * (i - 1) * (i - 2)\\end{cases} \] 没了 Code #include <algorithm> #include <ios

【题解】游戏

题目描述见Luogu P2462. 算法分析 其实这道题并不难,关键是如何转化.因为需要找到最长的单词接龙,就可以用图论来看.单词接龙不会出现环,所以,这就是个DAG上的拓扑排序.如果两个单词可以接在一起,就必须满足以下条件: 前一个单词的字母都必须在后一个单词中出现过 任意一个字母都不能少 后一个单词的长度比前一个单词多1,不能多也不能少 因为没有对顺序作要求,我们只需记录其出现次数即可,并存储它们的哈希值(hash/散列),枚举每个字符串的每个字母,增加其出现次数,并判断该字符串是否存在,如

Codeforces Round #263 (Div. 1) 题解

A:Appleman and Toastman 题意:两个人玩游戏 初始第一个人给第二个人一个数组 第二个人把数组中每个数相加的和加到他的总得分里面,然后把这个数组还给第一个人,第一个人进行操作:若数组中只剩下一个数,就把这个数组扔了,否则把这个数组拆成两个数组扔回给第二个人,求第二个人的最大得分. 题解:游戏结束即为数组中N个数全被拆成了单独的一个数,而且我们可以知道若一个数在第一个人操作第K次时候变成只有一个数的数组,那么这个数在第二个人那算了K+1次,于是不难想到贪心算法,即让越大的数算的

模拟赛(二):T118878 阴云密布(代码极度哲学,慎点)

2020.2.6 模拟赛(二) T1 阴云密布(改编) 题目描述 杰哥有三个属性:生命值,魔法值,能量值.杰哥有如下三种基本技能:充能,攻击,魔法.杰哥的初始生命值Ht1,能量值和魔法值为0.阿伟的初始生命值为Ht2. 战斗有n轮,每轮杰哥会发动3个基本技能(杰哥耍赖. 攻击Blast: 对于第i个基本技能,如果它是攻击,设能量值Pw,那么伤害为(Pw+1)?Fst1~i~.然后能量值清0. 充能Charge: 对于第i个基本技能,如果它是充能,那么伤害为Elc~i~.然后能量值增加1. 魔法A

codevs 1512 转向游戏 题解

Codevs 1512转向游戏 题解 时间限制: 1 s 空间限制: 1000 KB 题目等级 : 白银 Silver 题解 题目描述 Description 小明自认为方向感很好,请小红来测试.小红先让小明面对北方立正站好,然后发出"向左转""向右转"或"向后转"的命令.每个命令执行后,小明都正确地说出了他面对的方向.小红的命令共N个(1≤n≤10000),请你统计小明说[南]的次数. 命令是以数字方式表达: 0---向左转 1---向右转 2

洛谷 P1005 矩阵取数游戏 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1005 题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2.每次取走的各个元素只能是该元素所在行的行首或行尾: 3.每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元

洛谷 P1965 转圈游戏 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1965 题目描述 n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从0 到 n-1.最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 1 号位置,……,依此类推.游戏规则如下:每一轮第 0 号位置上的小伙伴顺时针走到第 m 号位置,第 1 号位置小伙伴走到第 m+1 号位置,……,依此类

Noip2007矩阵取数游戏题解

题目描述 Description [问题描述] 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n?m的矩阵,矩阵中的每个元素ai,j均 为非负整数.游戏规则如下: 每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 每次取走的各个元素只能是该元素所在行的行首或行尾: 每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分=被取走的元素值?2i, 其中i表示第i 次取数(从1 开始编号): 游戏结束总得分为m次取数得分之和. 帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出