zoukankan      html  css  js  c++  java
  • Round #446(Div 2)

    B. Wrath
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Hands that shed innocent blood!

    There are n guilty people in a line, the i-th of them holds a claw with length Li. The bell rings and every person kills some of people in front of him. All people kill others at the same time. Namely, the i-th person kills the j-th person if and only if j < i and j ≥ i - Li.

    You are given lengths of the claws. You need to find the total number of alive people after the bell rings.

    Input

    The first line contains one integer n (1 ≤ n ≤ 106) — the number of guilty people.

    Second line contains n space-separated integers L1, L2, ..., Ln (0 ≤ Li ≤ 109), where Li is the length of the i-th person's claw.

    Output

    Print one integer — the total number of alive people after the bell rings.

    Examples
    input
    4
    0 1 0 10
    output
    1
    input
    2
    0 0
    output
    2
    input
    10
    1 1 3 0 0 0 2 1 0 3
    output
    3
    Note

    In first sample the last person kills everyone in front of him.

     题意:前面一个人如果站在了后面一个人的武器长度范围内,就会被杀死

    也可以理解为,每个人站在对应下标位置,每个人因为得到自己数组下标及对应值的差,可以往前跑差值距离,前面的人也可以杀死更前面的人,更新可向前的人头数

    #include <bits/stdc++.h>
    #include <stdio.h>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    #define lowbit(x) (x&(-x))
    #define max(x,y) (x>=y?x:y)
    #define min(x,y) (x<=y?x:y)
    #define MAX 100000000000000000
    #define MOD 1000000007
    #define pi acos(-1.0)
    #define ei exp(1)
    #define PI 3.1415926535897932384626433832
    typedef long long ll;
    #define INF 0x3f3f3f3f
    #define mem(a) memset(a,0,sizeof(a))
    const int maxn=1e6+10;
    const long long  mod=9932107;
    int a[maxn];
    int maxx=INF;
    int solve(int n){
        int ans=0;
        for(int i=n-1;i>=0;i--){
            if(i>=maxx) ans++;
            maxx=min(maxx,i-a[i]);
        }
        return ans;
    }
    int main(){
        int n;
        mem(a);
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            ll x;
            scanf("%d",&x);
            a[i]=x;
        }
        int a=solve(n);
        printf("%d
    ",n-a);
        return 0;
    }
    C. Pride
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You have an array a with length n, you can perform operations. Each operation is like this: choose two adjacent elements from a, say xand y, and replace one of them with gcd(x, y), where gcd denotes the greatest common divisor.

    What is the minimum number of operations you need to make all of the elements equal to 1?

    Input

    The first line of the input contains one integer n (1 ≤ n ≤ 2000) — the number of elements in the array.

    The second line contains n space separated integers a1, a2, ..., an (1 ≤ ai ≤ 109) — the elements of the array.

    Output

    Print -1, if it is impossible to turn all numbers to 1. Otherwise, print the minimum number of operations needed to make all numbers equal to 1.

    Examples
    input
    5
    2 2 3 4 6
    output
    5
    input
    4
    2 4 6 8
    output
    -1
    input
    3
    2 6 9
    output
    4
    Note

    In the first sample you can turn all numbers to 1 using the following 5 moves:

    • [2, 2, 3, 4, 6].
    • [2, 1, 3, 4, 6]
    • [2, 1, 3, 1, 6]
    • [2, 1, 1, 1, 6]
    • [1, 1, 1, 1, 6]
    • [1, 1, 1, 1, 1]

    We can prove that in this case it is not possible to make all numbers one using less than 5 moves.

     首先可以先判断,如果数组中本来就有1的话,那么只要操作n-1次就可以满足题意

    然后判断连续gcd都没有得到1那就没有希望了,就是-1;

    最后就是隔了一段距离的情况,那就不断去寻找满足1最小子区间

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=2000;
     4 int a[maxn+5];
     5 int n;
     6 int ans=0;
     7 int gcd(int a,int b){
     8     return b==0?a:gcd(b,a%b);
     9 }
    10 int main(){
    11     scanf("%d",&n);
    12     memset(a,0,sizeof(a));
    13     for(int i=1;i<=n;i++){
    14         scanf("%d",&a[i]);
    15         if(a[i]==1) ++ans;
    16     }
    17     if(ans!=0) {
    18         printf("%d
    ",n-ans);
    19         return 0;
    20     }
    21     ans=n+1;
    22     for(int i=1;i<=n;i++){
    23         int sum=a[i];
    24         for(int j=i-1;j>=1;j--){
    25             sum=gcd(sum,a[j]);
    26             if(sum==1){
    27                 ans=min(ans,i-j);
    28             }
    29         }
    30     }
    31     if(ans==n+1){
    32         printf("-1
    ");
    33         return 0;
    34     }
    35     else printf("%d
    ",ans+n-1);
    36     return 0;
    37 }
  • 相关阅读:
    复杂JSON字符串转换为Java嵌套对象的方法
    好代码是如何炼成的
    让数据流转换代码更加健壮流畅:List的Stream包装
    由一个重构示例引发的对可扩展性的思考
    如何高效搜索信息
    个人安全防护简明指南
    YAML配置解析
    事件处理业务的简易组件编排框架
    lambda表达式滥用之殇:解耦三层嵌套lambda表达式
    碎碎念四六
  • 原文地址:https://www.cnblogs.com/z-712/p/7965268.html
Copyright © 2011-2022 走看看