HDU 6474 (循环节)

传送门

解题思路:

显然按按钮的过程中有循环节,找到循环节并记录一个循环按的次数和用的钱数以及一个循环中亏了最多的花费是多少

代码

#include <bits/stdc++.h>
using namespace std;
/*    freopen("k.in", "r", stdin);
    freopen("k.out", "w", stdout); */
// clock_t c1 = clock();
// std::cerr << "Time:" << clock() - c1 <<"ms" << std::endl;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define de(a) cout << #a << " = " << a << endl
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, a, n) for (int i = n; i >= a; i--)
#define ls ((x) << 1)
#define rs ((x) << 1 | 1)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<ll, ll> PLL;
typedef vector<int, int> VII;
#define inf 0x3f3f3f3f
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MAXN = 2e5 + 7;
const ll MAXM = 2e6 + 7;
const ll MOD = 1e9 + 7;
const double eps = 1e-6;
const double pi = acos(-1.0);
ll a[MAXN];
int vis[MAXN];
int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        ll n, k;
        scanf("%lld%lld", &n, &k);
        for (int i = 0; i < n; i++)
        {
            vis[i] = 0;
            scanf("%lld", &a[i]);
        }
        ll cnt = 0, minn = INF, tot = 0;
        ll ans = 0;
        while (!vis[k % n] && k >= 0)
        {
            ans++;
            vis[k % n] = 1;
            k += a[k % n];
        }
        if (k < 0)
            printf("%d\n", ans);
        else
        {
            int st = k % n;
            do
            {
                ans++;
                cnt++;
                tot += a[k % n];
                k += a[k % n];
                minn = min(tot, minn);
                if (k < 0)
                    break;
            } while (k % n != st);
            if (tot >= 0 && minn + k >= 0)
                printf("-1\n");
            else
            {
                ll lop = 0; //总圈数
                if ((k + minn) < 0)
                    lop = 0;
                else
                    lop += (k + minn) / -tot+((k + minn) % -tot != 0);
                ans += lop * cnt;
                k += lop * tot;
                while (k >= 0)
                {
                    ans++;
                    k += a[k % n];
                }
                printf("%lld\n", ans);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/graytido/p/12300734.html