zoukankan      html  css  js  c++  java
  • Codeforces Round #506 (Div. 3)

    C. Maximal Intersection

    【题目描述】

    You are given $n$ segments on a number line; each endpoint of every segment has integer coordinates. Some segments can degenerate to points. Segments can intersect with each other, be nested in each other or even coincide.
    The intersection of a sequence of segments is such a maximal set of points (not necesserily having integer coordinates) that each point lies within every segment from the sequence. If the resulting set isn't empty, then it always forms some continuous segment. The length of the intersection is the length of the resulting segment or $0$ in case the intersection is an empty set.
    Your task is to remove exactly one segment from the given sequence in such a way that the intersection of the remaining $(n−1)$ segments has the maximal possible length.

    【算法】

    	基本思路:显然对每一个区间,若将其作为删去的区间,则需计算剩余区间(的最大左值,和最小右值作为区间)的交集。我们设删去区间为第i个,则剩余区间的交集等价与1~i-1区间的交集和第i+1~n区间的交集的交集。
        综上我们可以预处理前后缀最大区间左值和最小区间右值,枚举remove的位置,O(1)的计算出剩余区间的交集,取长度的最大值。复杂度为O(n)。
    

    【代码】

    #include <bits/stdc++.h>
    using namespace std;
    int n,ans;
    int a[300010][2],pre[300010][2],post[300010][2];
    inline int read() {
        int x=0,f=1; char c=getchar();
        while(c<'0'||c>'9') { if(c=='-')f=-1; c=getchar(); }
        while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); }
        return x*f;
    }
    int main() {
        n=read(); post[n+1][1]=pre[0][1]=2e9;
        for(int i=1;i<=n;i++) a[i][0]=read(),a[i][1]=read();
        int max1=a[1][0],min1=a[1][1],max2=a[n][0],min2=a[n][1];
        for(int i=1;i<=n;i++) {
            max1=max(max1,a[i][0]),min1=min(min1,a[i][1]);
            max2=max(max2,a[n-i+1][0]),min2=min(min2,a[n-i+1][1]);
            pre[i][0]=max1,pre[i][1]=min1;
            post[n-i+1][0]=max2,post[n-i+1][1]=min2;
        }
        for(int i=1;i<=n;i++) {
            int l=max(pre[i-1][0],post[i+1][0]),r=min(pre[i-1][1],post[i+1][1]);
            ans=max(ans,r-l);
        }
        printf("%d
    ",ans);
        return 0;
    }
    
    

    D. Concatenated Multiples

    【题目描述】

    You are given an array $a$, consisting of $n$ positive integers.
    Let's call a concatenation of numbers $x$ and $y$ the number that is obtained by writing down numbers $x$ and $y$ one right after another without changing the order. For example, a concatenation of numbers $12$ and $3456$ is a number $123456$.
    Count the number of ordered pairs of positions $(i,j)$ $(i≠j)$ in array $a$ such that the concatenation of $a_i$ and $a_j$ is divisible by $k$.

    【算法】

    对任意一个数对$(a_i,a_j)$则$conc(a_i,a_j)=a_i⋅10{len(j)}+a_j$,由于$1≤a_j≤109$则对$a_i$最多左移10位,考虑枚举所有$a_i$,再枚举对左移1~10位,计算$mod(k)$为0或k时的$a_j$值,累加即可。注意用$map<int,int>[11]$对所有数进行预处理,记录$<mod(k)的值,个数>[位数]$,同时注意判$conc(a_i,a_i)$是否成立,若成立则结果减一。复杂度$O(10nlog_n)$。

    【代码】

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    ll ans;
    int n,k;
    int a[200010],power[11];
    map<int,int> rec[11];
    inline int read() {
        int x=0,f=1; char c=getchar();
        while(c<'0'||c>'9') { if(c=='-') f=-1; c=getchar(); }
        while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); }
        return x*f;
    }
    int main() {
        n=read(),k=read();
        power[0]=1;
        for(int i=1;i<=10;i++) power[i]=(ll)power[i-1]*10%k;
        for(int i=1;i<=n;i++) {
            a[i]=read(); int len=0,tmp=a[i];
            a[i]%=k;
            while(tmp) {
                len++;
                tmp/=10;
            }
            if(((ll)a[i]*power[len]+a[i])%k==0) ans--;
            if(rec[len].count(a[i])==0) rec[len].insert(make_pair(a[i],1));
            else rec[len][a[i]]++;
        }
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=10;j++) {
                int c=((ll)a[i]*power[j])%k;
                if(c&&rec[j].count(k-c)) ans+=rec[j][k-c];
                else if(!c&&rec[j].count(0)) ans+=rec[j][0];
            }
        }
        printf("%I64d
    ",ans);
        return 0;
    }
    
    
  • 相关阅读:
    结构层HTML + 表现层CSS
    移动端:项目实战
    移动端:开发技巧
    两个对象数组,把其中相同的name的before相加,不同的对象添加到数组里
    js中遍历数组和遍历对象
    css学习笔记一
    Angular2父子组件数据传递之@ViewChild获取子组件详解
    css知识点总结
    js中的apply,call,arguments,callee,caller详解
    javascript中的排序
  • 原文地址:https://www.cnblogs.com/Willendless/p/9538978.html
Copyright © 2011-2022 走看看