CF#613(div 2)

A. Mezo Playing Zoma

题意:

给你一串指令,只包含(L,R)表示向左向右移,但有些指令可能不起作用,问最后能到的位置有多少种可能

思路:

我们分析一下就可以知道,最终的结果时L的数目+R的数目+1

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main()
{
    string  t;
    int n;
    cin >> n;
    cin >> t;
   // set<int> s;
    //s.insert(0);
    int l = 0,r = 0;
    for(int i = 0;i<n;++i)
    {
       if(t[i]=='L')
        ++l;
       else
        ++r;
    }
    cout << r+l+1 << '\n';
    return 0;
}

B. Just Eat It!

题意:

给你一组数字,问能不能找到一个子区间[l,r],它的和大于等于[1,n],但[l,r]不能等于[1,n]

如果可以,输出No,否则输出YES

思路:

求取区间和,很明显,我们可以直接用尺取法来解决这个问题。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn =  1e5+10;
LL num[maxn];
int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        LL tmp = 0,sum = 0;
        cin >> n;
        for(int i = 1; i<=n; ++i)
        {
            cin >> num[i];
            sum+=num[i];
        }
        int l = 1,r = 1,ml = 1,mr = 1;
        LL ans = num[1],max_ans = num[1];
        for(int i  =2; i<=n; i++)
        {
            //cout << i << ": " << num[i] << " " << ans << endl;
           if(ans+num[i]>num[i])
           {
               ans+=num[i];
               ++r;
           }
           else
           {
               ans= num[i];
               l = r = i;
           }
            if(ans>max_ans)
               {
                   //cout << 1 << endl;
                   max_ans = ans;
                   ml = l;
                   mr = r;
               }
           if(max_ans>=sum)
            break;
        }
        if((ml==1&&mr==n)||max_ans<sum)
        {
            printf("YES\n");
        }
        else
        {
            printf("NO\n");
        }
    }
    return 0;
}

C. Fadi and LCM

题意:

给你一个数字X,让你求一对数ab,使得LCM(a,b) =X并且max(ab)最小

思路:

由上可以推断出,a,b一定X的因子,因此,枚举X的(互素)因子进行计算即可。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL a = 1,b=1;
void solve(LL x)
{
    //bool flag = false;
    LL max_x = x;
    LL a = 1, b = x;
   for(LL i = 1;i*i<=x;++i)
   {
       if(x%i==0)
       {
           if(__gcd(i,x/i)==1&&max(i,x/i)<max_x)
           {
               max_x = max(i,x/i);
               a = i;
               b = x/i;
           }
       }
   }
    cout << a << " " << b << endl;
}
int main()
{
   LL x;
   cin >> x;
   solve(x);
    return 0;
}

D. Dr. Evil Underscores

题意:

给你一组数,让你设定一个数X,使得X异或数组中每一个数的最大值最小,并输出这个最小值。

思路:

考虑二进制来解决当前问题,由题意可知,最多有30位,我们可以将每一个数展开为二进制形式。接下来从高位到低位,枚举每一位,假如当前位全是10,根据异或的性质,当前为要去与之相反的值,这对于最后的结果的贡献值是0,假如这一位有01,那么我们就需要两种情况都枚举下,但是无论哪种情况,对于最后答案的贡献都是1<<k(k表示是当前的第几位)

代码:

#include <bits/stdc++.h>
using namespace std;
int solve(int k,vector<int> p)
{
    if(p.size()==0||k<0)
        return 0;
    vector<int>p1,p2;
    for(int i = 0;i<p.size();i++)
    {
        if((p[i]>>k)&1)
            p1.push_back(p[i]);
        else
            p2.push_back(p[i]);
    }
    if(p1.size()==0)
        return solve(k-1,p2);
    else if(p2.size()==0)
        return solve(k-1,p1);
    else return (1<<k)+min(solve(k-1,p2),solve(k-1,p1));
}
int main()
{
    int n;
    scanf("%d",&n);
    vector<int> p(n);
    for(int i = 0;i<n;++i)
        scanf("%d",&p[i]);
    printf("%d\n",solve(29,p));
    return 0;
}

E. Delete a Segment

题意:

给你n条线段,求删除一条线段后,最多能有多少条线段(有交集的线段算是一条)。

思路:

可以参考下下面的博客

https://www.cnblogs.com/AaronChang/p/12192295.html

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 4e5+10;
pair<ll,ll>p[maxn];
int cnt[maxn];
int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        for(int i = 1;i<=n;++i)
        {
            ll l,r;
            cin >> l >> r;
            p[2*i-1] = make_pair(l,-i);
            p[2*i] =make_pair(r,i);
            cnt[i] =0;
        }
        sort(p+1,p+2*n+1);
        int ans = 0;
        multiset<int> s;
        for(int i = 1;i<=2*n;++i)
        {
            if(p[i].second<0)
                s.insert(-p[i].second);
            else
            {
                s.erase(s.find(p[i].second));
            }
            if(s.size()==0)
                ans++;
            if(s.size()==1&&p[i].second>0&&p[i+1].second<0&&p[i+1].first>p[i].first)
            {
                cnt[*s.begin()]++;
               // cout << *s.begin() << endl;
            }
            if(s.size()==1&&p[i].second<0&&p[i+1].second>0)
            {
                cnt[*s.begin()]--;
            }
        }
        int t =-1;
        for(int i =1;i<=n;++i)
            t = max(t,cnt[i]);
        cout << ans+t << endl;
    }
    return 0;
}

 

posted @ 2020-02-06 22:50  浅花迷人  阅读(181)  评论(0)    收藏  举报