zoukankan      html  css  js  c++  java
  • BZOJ 2976: [Poi2002]出圈游戏 HDU 5668 CRT

    2976: [Poi2002]出圈游戏

    题目连接:

    http://www.lydsy.com/JudgeOnline/problem.php?id=2976

    Description

    Input

    中第一行有一个正整数n, 2 <= n <= 20,第二行有n 个整数其中第i个整数表示编号为i 的小朋友第i个出圈。

    Output

    求最小的K,如果不存在,则输出一个单词“NO”

    Sample Input

    4

    1 4 2 3

    Sample Output

    5

    Hint

    题意

    题解:

    转化一下,其实就是模线性方程组,这个玩意儿用CRT怼一波就好了

    然而BZOJ这道题不是输出NO,而是输出NIE

    BC这道题却题面写错了,我比赛后才反应过来这道题的题意

    sad……

    代码是BZOJ的那道题代码,HDU的需要加上test,和 CA是SB这句话

    代码

    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int M = 30;
    
    long long Egcd (long long a, long long b, long long &x, long long &y)
    {
        if (b == 0)
        {
            x = 1, y = 0;
            return a;
        }
        long long d, tp;
        d = Egcd (b, a%b, x, y);
        tp = x;
        x = y;
        y = tp - a/b*y;
        return d;
    }
    
    long long CRT2 (long long b[], long long n[], int num)
    {
        int i;
        bool flag = false;
        long long n1 = n[0], n2, b1 = b[0], b2, bb, d, t, k, x, y;
        for (i = 1; i < num; i++)
        {
            n2 = n[i], b2 = b[i];
            bb = b2 - b1;
            d = Egcd (n1, n2, x, y);
            if (bb % d)     //模线性解k1时发现无解
            {
                flag = true;
                break;
            }
            k = bb / d * x;    //相当于求上面所说的k1【模线性方程】
            t = n2 / d;
            if (t < 0) t = -t;
            k = (k % t + t) % t;    //相当于求上面的K`
            b1 = b1 + n1*k;
            n1 = n1 / d * n2;
        }
        if (flag)
            return -1;           //无解
        return b1;    //形成的解:b1, b1+n1, b1+2n1,..., b1+xni...
    }
    int vis[30];
    long long b[M], n[M];
    long long t, num, i, cc = 1;
    pair<int,int>P[M];
    int main()
    {
        scanf ("%d",&num);
        for (i = 0; i < num; i++)
            n[i]=num-i;
        for (i = 0; i < num; i++)
        {
            scanf("%d",&P[i].first);
            P[i].second = i;
        }
        sort(P,P+num);
        int las = num-1;
        for (i = 0; i < num; i++)
        {
            int x;x=P[i].second;
            int ttt = 0;
            while(1)
            {
                las++;
                las%=num;
                if(vis[las])continue;
                if(las==x)
                {
                    b[i]=ttt;
                    vis[las]=1;
                    break;
                }
                ttt++;
            }
        }
        long long p = CRT2(b,n,num);
        if(p==-1)printf("NIE
    ");
        else printf("%lld
    ",p+1);
        return 0;
    }
  • 相关阅读:
    Note/Solution 转置原理 & 多点求值
    Note/Solution 「洛谷 P5158」「模板」多项式快速插值
    Solution 「CTS 2019」「洛谷 P5404」氪金手游
    Solution 「CEOI 2017」「洛谷 P4654」Mousetrap
    Solution Set Border Theory
    Solution Set Stirling 数相关杂题
    Solution 「CEOI 2006」「洛谷 P5974」ANTENNA
    Solution 「ZJOI 2013」「洛谷 P3337」防守战线
    Solution 「CF 923E」Perpetual Subtraction
    KVM虚拟化
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5399851.html
Copyright © 2011-2022 走看看