• Codeforces Global Round 7


     

         地址:http://codeforces.com/contest/1326

         题意:给定n,输出一个长度为n的数字,满足以下条件:1:>0  2:各个位上不出现0  3:不能整除自己的任意一位。

         解析:被这题给坑了一下。想不通我的33......7为什么不行,可能太长的话有被7整除的危险,并不能保证万无一失。所以我们需要一个能保证万无一失的通用方法。一个是2333.....3,或是5333.......3。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+10;
    int a[maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n;
            cin>>n;
            if(n==1)
                cout<<"-1"<<endl;
            else
            {
                cout<<"2";
                for(int i=1;i<n;i++)
                    cout<<"3";
                    cout<<endl;
            }
        }
    }

         题意:有点小绕,大致就是我画的这个意思。

         很明显,题意中有讲,x1=0固定。则a1=b1,直接规定maxx=a1,用这个maxx来维护数组a[]的i-1之前的最大值。ai=bi+maxx,然后更新maxx=max(maxx,bi+maxx);这个顺序不要错。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int maxn=2e5+10;
    ll b[maxn];
    ll a[maxn];
    int main()
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
            cin>>b[i];
        int x;
        a[1]=b[1];
        ll maxx=a[1];
        for(int i=2;i<=n;i++)
        {
            a[i]=b[i]+maxx;
            maxx=max(maxx,b[i]+maxx);
        }
        for(int i=1;i<=n;i++)
        {
            if(i<n)
                cout<<a[i]<<" ";
            else
                cout<<a[i]<<endl;
        }
    }

         题意:也是绕的一批,我这个英语渣压根就没看懂,靠队友才搞懂。

             就是更定一个数量n的数组以及一个k对这个数组进行分块,{|...|,|...|}k是多少,大括号里面就有几个|...|集合,里面是L,R,均为下标。集合之间不能有重叠,要保证全覆盖数组。可以把每个|...|里的最大值提出来,k个最大值相加,得到一个数。目的是找出这个最大数来,以及可以弄出这个数的分块方式有几种。

        解析:既然是k个集合,那么要想保证各个最大值加起来最大,那么就要把前k个大的数做为每个集合里的最大值。以此为基准进行分块操作。再画个图看看:假设k=3

         三角号表示分界线可放的地方,是不是还是不明白怎么算?没关系,举个例子:有前k大数 a,b。a与b挨着,那么分界线只能插在a上,1种,i+1-i=1,所以根据这个数目就是它们坐标之差。总之就是,记录前k大数的各个坐标之差,乘起来就好了。记得题意里说结果要mod 998244353

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int maxn=2e5+10;
    int main()
    {
        int n,k;
        cin>>n>>k;
        ll ans=1;
        int idx=-1;
        int x=0;
        ll sum=0;
        for(int i=1;i<=n;i++)
        {
            cin>>x;
            if(x>=n-k+1)
            {
                sum+=x;
                if(idx!=-1)
                {
                    ans=(ans*(i-idx))%998244353;
                //    cout<<i-idx<<endl;
                }
                idx=i;
            }
        }
        cout<<sum<<" "<<ans<<endl;
    }

     

         题意:给你一个字符串,从中找出一个子序列是字符串前缀与字符串后缀(可为空)拼接成的最长回文子字符串。

         解析:首先找前后缀构成的回文:

            while(l<r&&s[l]==s[r])
                l++,r--;

            注意了,这个算出来L是比实际+1,R是比实际-1的。便于下面的找中间最长回文(要它与左前缀相连或者与右后缀相连)。在L-R之间找最长回文,用r2=R,l2=L:分别固定L和R来进行中间r2,l2的滑动寻找回文串:

          PS:substr(l,d)返回的是以l下标为开头,长度为d的字符串。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int check(string &s,int l,int r)
    {
        while(l<=r&&s[l]==s[r])
        {
            l++;
            r--;
        }
        return r<l?1:0;  //如果r<l了,肯定是回文串了,返回1,否则返回0
    }
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            string s;
            cin>>s;
            int len=s.length();
            int l=0,r=len-1;
            while(l<r&&s[l]==s[r])
                l++,r--;
            int l2,r2;
            for(r2=r;r2>=l;r2--)
            {
                if(check(s,l,r2))
                {
                    break;
                }
            }
            for(l2=l;l2<=r;l2++)
            {
                if(check(s,l2,r))
                    break;
            }
    //        cout<<l2<<" "<<r2<<endl;
            cout<<s.substr(0,l);    //L算出来比实际+1的,长度即为L-1-0+1=L;
            if((r2-l)>(r-l2))
                cout<<s.substr(l,r2-l+1);
            else
                cout<<s.substr(l2,r-l2+1);
            cout<<s.substr(r+1)<<endl;//R算出来是比实际-1的,直接是输出r+1到串尾
        }
    }
  • 相关阅读:
    与平面和空间打交道的计算几何
    借助水流解决问题的网络流
    计算几何算法概览
    关于while (~scanf("%d %d", &m, &n))的用法
    Minimizing maximizer(POJ 1769)
    java九九乘法表
    java替换字符串中的World为Money
    java截取字符串,第4位以后的字符串用*代替
    java使用valueOf的方法反转字符串输出
    java使用StringBuilder的方法反转字符串输出
  • 原文地址:https://www.cnblogs.com/liyexin/p/12535868.html
Copyright © 2020-2023  润新知