[题解]AtCoder Beginner Contest 174

AtCoder Beginner Contest 174

闲来无事摸了一场ABC

A

按题意模拟即可 \(\leq 30\)输出 Yes 否则 No

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a) & -(a))
#define clean(a, b) memset(a, b, sizeof(a))
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int maxn = 2e6 + 9;

int _;

//========================================================================

//========================================================================
int main()
{
    int n;
    scanf("%d",&n);
    if(n>=30) puts("Yes");
    else puts("No");
    
    return 0;
}

B

给你一些坐标 问有多少坐标与原点距离小于\(d\)
怕有误差可以把开根号换成\(d*d\) 记得开long long
(大于小于看反了 慢了几分钟)

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a) & -(a))
#define clean(a, b) memset(a, b, sizeof(a))
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int maxn = 2e6 + 9;

int _;

//========================================================================

//========================================================================
int main()
{
    ll n,d,x,y,cnt=0;
    scanf("%lld%lld",&n,&d);
    d=d*d;
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld",&x,&y);
        if(d>=x*x+y*y) cnt++;
    }
    printf("%lld\n",cnt);
    
    return 0;
}

C

有一个序列\(7,77,777,7777……\)
给你一个数k,问k的倍数是否有可能是上述序列中的元素
如果是,请输出最小是几个七

貌似可以暴力做,最大就是\(k\)\(7\)
首先只有尾数是\(1,3,7,9\)的数的倍数结尾有可能是\(7\)
其次 有\(1\leq i\leq k\),如果\(i\)\(7\% k==0\)那么输出i就可以了,否则-1
要用到高精取模 学到了学到了
我的代码还要特判\(1\)\(7\) 可能是写法问题

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a) & -(a))
#define clean(a, b) memset(a, b, sizeof(a))
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int maxn = 2e6 + 9;

int _;

//========================================================================

//========================================================================
int main()
{
    int n,sum=7;
    scanf("%d",&n);
    if(n%2==0) 
    {
        printf("-1\n");
        return 0;
    }
    if(n==1||n==7) 
    {
        printf("1\n");
        return 0;
    }
    for(int i=1;i<=n;i++)
    {
        if(sum==0) 
        {
            printf("%d\n",i);
            return 0;
        }
        sum=(sum*10+7)%n;
    }
    printf("-1\n");
    return 0;
}

D

只可以通过把w变成R或者把R变成W或者交换RW使得W左边没有R
那么这三种情况肯定有一个最优的,取最小就可
(但事实上好像只判断第三种就可以)

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a) & -(a))
#define clean(a, b) memset(a, b, sizeof(a))
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 + 9;

int _;

//========================================================================
char s[maxn];
//========================================================================
int main()
{
    int n;
    scanf("%d",&n);
    scanf("%s",s);
    int num1=0,num2=0;
    for(int i=0;i<n;i++)
    {
        if(s[i]=='W') num1++;
        else num2++;
    }
    int cnt=0;
    for(int i=0;i<n;i++)
    {
        if(i<num2) 
        {
            if(s[i]!='R') cnt++;
        }
        else 
        {
            if(s[i]!='W') cnt++;
        } 
    }
    printf("%d\n",min(num1,min(num2,cnt/2)));
    return 0;
}

E

给你一些长度的木头,只可以砍k次,使得砍完的木头们的最高高度最矮,输出最高高度
想挺久的不知道怎么分配
后来突然想到 可以二分答案做,如果高度很小,那就是不成立的,如果高度很高,那一定成立,存在单调性,根据题意,求的就是满足条件的最小值

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a) & -(a))
#define clean(a, b) memset(a, b, sizeof(a))
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int maxn = 2e6 + 9;

int _;

//========================================================================
int a[maxn],n,k;
bool check(int now)
{
    int sum=0;
    for(int i=1;i<=n;i++)
    {
        sum+=(a[i]-1)/now;
    }
    if(sum<=k) return 1;
    return 0;
}
int two_points(int minn,int maxx)
{
    int l=minn,r=maxx,mid,ans;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(check(mid)) r=mid-1;
        else l=mid+1;
        ans=r+1;
    }
    return ans;
}
//========================================================================
int main()
{
    int maxx=0;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        maxx=max(maxx,a[i]);
    }
    int ans=two_points(1,maxx);
    printf("%d\n",ans);
    return 0;
}

F

给你一个序列,每个数字代表一种颜色
有q组询问 每组询问问在[l,r]内有多少种不同的颜色
这题很眼熟欸,洛谷原题 HH的项链 树状数组or线段树

首先对于[l,r]每个颜色最有用的就是在这个区间内最靠右的位置,那么每个颜色我们只保留最右边的那个,然后再进行区间和的查询
实现的方式也很简单,我们先记下来对于当前位置,与他相同颜色的前一个位置是在哪里,把他这个位置的值-1,把当前位置的值+1(对于与他相同颜色的前一个位置存在,那么那个位置的数值一定加过了,如果不存在,就不加)
先对q组询问离线处理,按r排序可以降低复杂度,每次对于x[i-1].r到x[i].r,更新这个区间内的颜色(把当前位置颜色相同是上一个位置的值-1,把当前位置的值+1)
更新过后取sum(r)-sum(l-1)即可

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(a) ((a) & -(a))
#define clean(a, b) memset(a, b, sizeof(a))
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int maxn = 2e6 + 9;

int _;

//========================================================================
int c[maxn],a[maxn],last[maxn],pre[maxn],n,ans[maxn];
struct node
{
    int l,r,num;
}x[maxn];
int cmp(node a,node b)
{
    if(a.r==b.r) return a.l<b.l;
    return a.r<b.r;
}
void update(int x,ll y,int n)///One point update
{
    for(int i=x; i<=n; i+=lowbit(i))
        c[i] += y;
}
ll get_sum(int x)///Interval query
{
    ll ans = 0;
    for(int i=x; i; i-=lowbit(i))
        ans += c[i];
    return ans;
}
//========================================================================
int main()
{
    int q;
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if(last[a[i]])
        {
            pre[i]=last[a[i]];
            last[a[i]]=i;
        }
        else 
        {
            pre[i]=maxn+1;
            last[a[i]]=i;
        }
    }
    for(int i=1;i<=q;i++)
    {
        scanf("%d%d",&x[i].l,&x[i].r);
        x[i].num=i;
    }
    sort(x+1,x+1+q,cmp);
    int j=1;
    for(int i=1;i<=q;i++)
    {
        for(;j<=x[i].r;j++)
        {
            update(pre[j],-1,n);
            update(j,1,n);
        }
        ans[x[i].num]=get_sum(x[i].r)-get_sum(x[i].l-1);
    }
    for(int i=1;i<=q;i++) printf("%d\n",ans[i]);
    return 0;
}

posted @ 2020-08-03 14:01  L·S·D  阅读(188)  评论(0编辑  收藏  举报