In mathematics you don't understand things, you just get used to them.

「CF 1520A」Do Not Be Distracted!

Link.

模拟。

#include<bits/stdc++.h>
char now;
char get_char(){char res=getchar();while(res<'A' || res>'Z')    res=getchar(); return res;}
bool vis[26];
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T-->0)
    {
        scanf("%d",&n);
        int ans=0;
        for(int i=1;i<=n;++i)
        {
            char cur=get_char();
            if(cur!=now)
            {
                now=cur;
                if(vis[cur-'A'])    ans=1;
            }
            vis[cur-'A']=1;
        }
        puts(ans?"NO":"YES");
        memset(vis,0,sizeof vis);
    }
    return 0;
}

「CF 1520B」Ordinary Numbers

Link.

按位考虑。

#include<bits/stdc++.h>
typedef long long ll;
int main()
{
    int T;
    scanf("%d",&T);
    while(T-->0)
    {
        ll ans=0,n;
        scanf("%lld",&n);
        for(ll pw=1;pw<=n;pw=pw*10+1)    for(int now=1;now<=9;++now)    if(pw*now<=n)    ++ans;
        printf("%lld\n",ans);
    }
    return 0;
}

「CF 1520C」Not Adjacent Matrix

Link.

用 flows 的 trick 来构造,$(i+j)$ 为奇先填,为偶后填。

#include<bits/stdc++.h>
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T-->0)
    {
        scanf("%d",&n);
        if(n==2)    puts("-1");
        else
        {
            int cur=0;
            static int ans[110][110];
            for(int i=1;i<=n;++i)    for(int j=1;j<=n;++j)    if((i+j)&1)    ans[i][j]=++cur;
            for(int i=1;i<=n;++i)    for(int j=1;j<=n;++j)    if((i+j)&1^1)    ans[i][j]=++cur;
            for(int i=1;i<=n;++i,puts(""))    for(int j=1;j<=n;++j)    printf("%d ",ans[i][j]);
        }
    }
    return 0;
}

「CF 1520D」Same Differences

Link.

式子移项。

#include<bits/stdc++.h>
typedef long long ll;
int a[200010],cnt[500010];
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T-->0)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i)    scanf("%d",&a[i]),a[i]-=i,a[i]+=200000,++cnt[a[i]];
        ll ans=0;
        for(int i=1;i<=n;++i)    ans+=cnt[a[i]]-1;
        printf("%lld\n",ans/2);
        for(int i=1;i<=n;++i)    --cnt[a[i]];
    }
    return 0;
}

「CF 1520E」Arranging The Sheep

Link.

所有牛往中间那头牛走。

#include<bits/stdc++.h>
typedef long long ll;
#define All(x) (x).begin(),(x).end()
int fuck[1000010];
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T-->0)
    {
        scanf("%d",&n);
        int tot=0;
        for(int i=1;i<=n;++i)
        {
            char now=getchar();
            while((now^    '.') && (now^'*'))    now=getchar();
            if(now=='*')    fuck[++tot]=i;
        }
        int mpos=int(std::ceil(tot/2.0));
        ll ans=0;
        for(int i=1;i<=tot;++i)    ans+=std::abs(fuck[i]-fuck[mpos]+mpos-i);
        printf("%lld\n",ans);
    }
    return 0;
}

「CF 1520F1」Guess the K-th Zero (Easy version)

Link.

二分维护答案区间,询问 $\log_{2}$ 次。

#include<bits/stdc++.h>
#define fl fflush(stdout)
int n,t,k;
int q(int l,int r){int res=0; printf("? %d %d\n",l,r); fl; scanf("%d",&res); return res;}
int main()
{
    scanf("%d %d",&n,&t);
    while(t--)
    {
        scanf("%d",&k);
        int l=1,r=n,ans=0;
        while(l<=r)
        {
            int mid=(l+r)>>1,tmp=mid-l+1-q(l,mid);
            if(tmp>=k)    r=mid-1,ans=mid;
            else    k-=tmp,l=mid+1;
        }
        printf("! %d\n",ans);
        fl;
    }
    return 0;
}

「CF 1520F2」Guess the K-th Zero (Hard version)

Link.

把二分记忆化下来,用 std::map 和 BIT 实现。

#include<bits/stdc++.h>
#define fl fflush(stdout)
int n,t,k;
struct FWT
{
    #define l(x) ((x)&-(x))
    int tr[200010];
    FWT(){memset(tr,0,sizeof tr);}
    void i(int x){for(;x<=n;x+=l(x))    ++tr[x];}
    int $(int x){int r=0; for(;x;x^=l(x))    r+=tr[x]; return r;}
    int f(int l,int r){return $(r)-$(l-1);}
}fw;
std::map<std::tuple<int,int>,int> mp;
int q(int l,int r){
    if(mp.find(std::tie(l,r))==mp.end())
    {
        int res=0;
        printf("? %d %d\n",l,r);
        fl;
        scanf("%d",&res);
        mp[std::tie(l,r)]=res;
        return res;
    }
    else    return mp[std::tie(l,r)]+fw.f(l,r);
}
int main()
{
    scanf("%d %d",&n,&t);
    while(t--)
    {
        scanf("%d",&k);
        int l=1,r=n,ans=0;
        while(l<=r)
        {
            int mid=(l+r)>>1,tmp=mid-l+1-q(l,mid);
            if(tmp>=k)    r=mid-1,ans=mid;
            else    k-=tmp,l=mid+1;
        }
        printf("! %d\n",ans);
        fl;
        fw.i(ans);
    }
    return 0;
}

「CF 1520G」To Go Or Not To Go?

Link.

广搜。

#include<bits/stdc++.h>
typedef long long ll;
#define sf(x) scanf("%d",&x)
#define ssf(x) scanf("%lld",&x)
const int wax[4]={1,-1,0,0},way[4]={0,0,1,-1};
int n,m;
ll w,dis0[2010][2010],dis1[2010][2010],a[2010][2010];
bool Inside(int x,int y){return !(x<1 || x>n || y<1 || y>m);}
void Compute_0()
{
    std::queue<std::tuple<int,int>> q;
    q.emplace(1,1);
    dis0[1][1]=1;
    while(!q.empty())
    {
        int nowx,nowy;
        std::tie(nowx,nowy)=q.front();
        q.pop();
        for(int k=0;k<4;++k)
        {
            int tox=nowx+wax[k],toy=nowy+way[k];
            if(Inside(tox,toy) && !dis0[tox][toy] && ~a[tox][toy])    dis0[tox][toy]=dis0[nowx][nowy]+1,q.emplace(tox,toy);
        }
    }
    for(int i=1;i<=n;++i)    for(int j=1;j<=m;++j)    --dis0[i][j];
}
void Compute_1()
{
    std::queue<std::tuple<int,int>> q;
    q.emplace(n,m);
    dis1[n][m]=1;
    while(!q.empty())
    {
        int nowx,nowy;
        std::tie(nowx,nowy)=q.front();
        q.pop();
        for(int k=0;k<4;++k)
        {
            int tox=nowx+wax[k],toy=nowy+way[k];
            if(Inside(tox,toy) && !dis1[tox][toy] && ~a[tox][toy])    dis1[tox][toy]=dis1[nowx][nowy]+1,q.emplace(tox,toy);
        }
    }
    for(int i=1;i<=n;++i)    for(int j=1;j<=m;++j)    --dis1[i][j];
}
int main()
{
    sf(n),sf(m),ssf(w);
    for(int i=1;i<=n;++i)    for(int j=1;j<=m;++j)    ssf(a[i][j]);
    Compute_0(),Compute_1();
    ll mxtmp=std::numeric_limits<ll>::max();
    ll ans=~dis0[n][m]?w*dis0[n][m]:mxtmp,ozd=mxtmp;
    for(int i=1;i<=n;++i)    for(int j=1;j<=m;++j)    if(~dis1[i][j] && a[i][j]>=1)    ozd=std::min(ozd,a[i][j]+w*dis1[i][j]);
    for(int i=1;i<=n;++i)    for(int j=1;j<=m;++j)    if(~dis0[i][j] && a[i][j]>=1 && ozd!=mxtmp)    ans=std::min(ans,w*dis0[i][j]+a[i][j]+ozd);
    if(ans==mxtmp)    puts("-1");
    else    printf("%lld\n",ans);
    return 0;
}

binary search greedy bitwise constructive algorithms

Solution -「THUPC 2021」区间矩阵乘法
上一篇 «
Solution -「HNOI 2010」城市建设
» 下一篇