Lucky Sorting(CodeForces-109D)[思维]

题意:给出一组数,要求从小到大排序,并且排序的过程中,发生交换的两个数至少一个为幸运数(十进制位均为4或7),问能否在(2×n)次交换内完成排序,如果能,输出交换的方案(不要求步骤数最少)。

思路:首先分为两种情况:

    1.所有的数均不为幸运数,则如果给出的序列已经排好序,答案为0,如果未排好序,则无法完成排序。

    2.存在幸运数,可得,只要存在幸运数,就一定能在2×n次以内完成排序。

      <1>具体的处理方法是将序列分为若干个闭环,闭环的意思可以举个例子来看,(xio表示下标为xi的元素排序后所在位置下标),如:x1->x2->x3->x1,这就是一个闭环,表示x1o==x2,x2o=x3,x3o=x1;

      <2>首先,一组数在上述规则下一定能分为若干闭环。

      <3>分完闭环后,正式进行交换,并且,确定一个幸运数作为操作数(需要且只需要一个),记录其所在闭环

        3.1首先,将操作数所在闭环进行排序(只需相邻之间两两交换即可,具体可参照上文对于闭环的定义)。

        3.2再借助操作数对剩余闭环依次排序。第一步为将操作数与待排序闭环中的任意元素交换,再用3.1中的方法操作,最后将操作数归位即可。

        3.3很容易证明,上述交换操作的总复杂度一定小于2×n.

代码如下:

  

#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef pair<int, int> P;
int n, arr[100010], inde[100010];
bool judge(int x)
{
    while (x != 0)
    {
        if (x % 10 != 4 && x % 10 != 7)
            return false;
        x /= 10;
    }
    return true;
}

bool cmp(int a, int b)
{
    return arr[a] < arr[b];
}
int main()
{
    int px = 0;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        inde[i] = i;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &arr[i]);
        if (!px && judge(arr[i]))
            px = i;
    }
    sort(inde + 1, inde + 1 + n, cmp);
    int iinde[100010];
    for (int i = 1; i <= n; i++)
    {
        iinde[inde[i]] = i;
    }
    if (!px)
    {
        int tans = 0;
        for (int i = 1; i <= n; i++)
            if (inde[i] != i)
            {
                tans = -1;
                break;
            }
        printf("%d", tans);
    }
    else
    {
        vector

ans; int book[100010] = {0}; vector<int> aha[100010]; int numAha[100010] = {0}, rd = 0, fgp; for (int i = 1; i <= n; i++) { if (book[i]) continue; rd++; int p = i; while (!book[p]) { book[p] = 1; aha[rd].push_back(p); if (p == px) fgp = rd; p = inde[p]; } } //flagRound memset(book, 0, sizeof(book)); if (aha[fgp].size() > 1) { int ic = px; while (!book[inde[ic]]) { book[ic] = 1; ans.push_back(P(ic, inde[ic])); ic = inde[ic]; } } //restRound for (int i = 1; i <= rd; i++) { if (i == fgp || aha[i].size() == 1) continue; int ic = aha[i][0]; ans.push_back(P(iinde[px], ic)); while (!book[inde[ic]]) { book[ic] = 1; ans.push_back(P(ic, inde[ic])); ic = inde[ic]; } ans.push_back(P(iinde[px], iinde[aha[i][0]])); } printf("%d\n", ans.size()); for (int i = 0; i < ans.size(); i++) { printf("%d %d\n", ans[i].first, ans[i].second); } } return 0; }

By xxmlala

 

你可能感兴趣的:(Lucky Sorting(CodeForces-109D)[思维])