2022/7/15

142 篇文章 1 订阅
92 篇文章 0 订阅

P6121 [USACO16OPEN]Closing the Farm G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)并查集

之前做过这道题,现在又不会了,,,关键是要想到要反着考虑,将正着关闭相成反着打开,从n-1个开始记录加的边有多少条,如果加的边数为点数-1,那么就是连通的

2022/1/29_killer_queen4804的博客-CSDN博客

#include <bits/stdc++.h>
#define ll long long
#define lowbit(x) ((x)&(-x))
using namespace std;
const ll mod=998244353;
ll n,m,s[200005],ans[200005],vis[200005],t[200005];
ll head[500005],cnt;
struct Edge{
    ll next,from,to;
}edge[500005];
void addedge(ll from,ll to){
    edge[++cnt].from=from;
    edge[cnt].to=to;
    edge[cnt].next=head[from];
    head[from]=cnt;
}
ll findd(ll x){
    return x==s[x]?x:s[x]=findd(s[x]);
}
int main(){
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=m;i++){
        ll u,v;
        scanf("%lld%lld",&u,&v);
        addedge(u,v);
        addedge(v,u);
    }
    for(int i=1;i<=n;i++) scanf("%lld",&t[i]);
    for(int i=1;i<=n;i++) s[i]=i;
    vis[t[n]]=1;
    ans[n]=1;
    ll k=0;
    for(int i=n-1;i>=1;i--){
        vis[t[i]]=1;
        for(int j=head[t[i]];j;j=edge[j].next){
            if(vis[edge[j].to]){
                ll x=findd(t[i]),y=findd(edge[j].to);
                if(x!=y){
                    k++;
                    s[x]=y;
                }
            }
        }
        if(k==n-i) ans[i]=1;
        else ans[i]=0;
    }
    for(int i=1;i<=n;i++)
        if(ans[i]) printf("YES\n");
    else printf("NO\n");
    return 0;
}

Palindromic Numbers 构造

输出的数必须和给出的数数位相同才行,也就是说都得是n位,可以考虑拿99来说,可以考虑111这个回文数,那么答案就是12,然后可以发现999答案就是112,9999答案就是1112,位数一样,且大部分数都可以用多一位的111...减去给出的数得到答案,但是比1..2小的数就不行了,这样可以用1000..01这种形式的数减去给出的数得到答案

#include <bits/stdc++.h>
#define ll long long
#define lowbit(x) ((x)&(-x))
using namespace std;
const ll mod=998244353;
ll t,n;
char s[100005],c[100005],ans[100005],ch[100005];
bool pd(){
    for(int i=1;i<=n;i++){
        if(s[i]<ch[i]) return 0;
        if(s[i]>ch[i]) return 1;
    }
    return 1;
}
int main(){
    scanf("%lld",&t);
    while(t--){
        scanf("%lld",&n);
        scanf("%s",s+1);
        for(int i=1;i<n;i++) ch[i]='1';ch[n]='2';
        if(pd()){
            for(int i=1;i<=n+1;i++) c[i]='1';
        }
        else{
            for(int i=2;i<=n;i++) c[i]='0';c[1]=c[n+1]='1';
        }
        for(int i=n;i>=1;i--){
            if(c[i+1]<s[i]){
                    c[i+1]+=10;
                    ll cnt=i;c[cnt]--;
                    while(cnt>0&&c[cnt]<0){
                        c[cnt]+=10;
                        c[--cnt]--;
                    }
            }
            //cout<<c[i+1]<<" "<<s[i]<<" "<<(c[i+1]-'0')-(s[i]-'0')<<endl;
            ans[i]=(c[i+1]-'0')-(s[i]-'0')+'0';
        }
        for(int i=1;i<=n;i++) cout<<ans[i];cout<<'\n';
    }
    return 0;
}

Helping the Nature 差分

题目看完后有点无从下手,但是求出一个差分数组来就可以发现,之前按的三种操作变成了

b[1]-1,b[i]+1;b[1]+1;b[i]-1;这三种操作,这样我们尽可能使用第1种操作,因为可以同时改变两个,之后再去用其他两个,我们的目的是差分数组都变为0,所以有时候b[i](i>1)会小于0并且光靠第一种操作不能让b[i]=0,所以要借助第二种操作让b[1]增加,b[i]都大于等于0后就可以用第三种操作依次消去了,代码里直接简化成一两个公式了,但意思都一样

#include <bits/stdc++.h>
#define ll long long
#define lowbit(x) ((x)&(-x))
using namespace std;
const ll mod=998244353;
ll t,n,a[200005],b[200005];
int main(){
    scanf("%lld",&t);
    while(t--){
        scanf("%lld",&n);
        ll sum=0,ans=0;
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]),b[i]=a[i]-a[i-1];
            if(i>1){
                sum+=b[i]<0?abs(b[i]):0;
                ans+=abs(b[i]);
            }
        }
        ans+=abs(b[1]-sum);
        printf("%lld\n",ans);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

killer_queen4804

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值