2022/3/28

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

D1 - 388535 (Easy Version)

关于位运算的题目练的还是少啊,这种东西通过打表很难看出规律的,,另外做思维题也要规定好时间,不然半下午加半晚上才看了一道题还没做出来,心里得多难受,而且训练效果也一塌糊涂;

最终要满足条件的话,要达到a[i]^x<=r,最后的a[0]+a[1]+...+a[r]==0+1+...r;(加上一句看的解释:题目肯定规定了一定有解,再加上x与其他数异或一定不同,所以我们只需要让和最小即可)说实话网上的题解说的思路太牵强了,但也没办法,这种题是需要灵机一动或者是阅历丰富的;如果某个位上1的个数大于0的个数,ans就加上这位;但是也知道了一点东西,位运算的题目尽量要去往位运算的特点(按位运算上靠)

Codeforces Round #779 (Div. 2) A~D2 - 知乎 (zhihu.com)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll t,l,r,cnt[30][2],x;
int main(){
    //freopen("in.txt","r",stdin);
    cin>>t;
    while(t--){
        for(int i=0;i<=30;i++) cnt[i][0]=cnt[i][1]=0;
        cin>>l>>r;
        for(int i=l;i<=r;i++){
            cin>>x;
            for(int j=0;j<30;j++)
            cnt[j][(x>>j)&1]++;
        }
        ll ans=0;
        for(int i=0;i<30;i++)
            if(cnt[i][1]>cnt[i][0]) ans+=(1<<i);
        cout<<ans<<endl;
    }
	return 0;
}

C - Shinju and the Lost Permutation

其实可以发现每个c[i]出现是有一定规律的,他们是循环着出现的,就比如样例

6
2 3 1 2 3 4

可以看成是从一开始 1 2 3 4 1 2 3 4以此类推,还可以发现1只会出现一次,我们可以从1开始进行,将上面的样例变为1 2 3 4 2 3因为是循环所以可以改变一定的顺序,然后发现小数到大数每次只能加1,而大数到小数都是可以的;然后就根据这个条件来判断就行了;一开始把这个问题想复杂了,关键是没有想到1这个点;

Codeforces Round #779 (Div. 2) C(思维) D1(位运算) - 知乎 (zhihu.com)

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll t,n,a[100005];
vector<ll>v,b;
int main(){
    //freopen("in.txt","r",stdin);
    scanf("%lld",&t);
    while(t--){
        v.clear();b.clear();
        scanf("%lld",&n);
        ll one=0;
        for(int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            if(a[i]==1) one++;
        }
        if(one!=1){
            printf("NO\n");
            continue;
        }
        for(int i=1;i<=n;i++){
            if(a[i]==1){
                for(int j=i;j<=n;j++) b.push_back(a[j]);
                for(int j=0;j<v.size();j++) b.push_back(v[j]);
            }
            else v.push_back(a[i]);
        }
        bool flag=1;
        for(int i=1;i<b.size();i++){
            if(b[i]-b[i-1]>=2){flag=0;break;}
        }
        if(flag) printf("YES\n");
        else printf("NO\n");
    }
	return 0;
}

580C - Kefa and Park dfs

好像有一段时间没做dfs了,因为我比较喜欢bfs,这题应该也可以用bfs。。。

连好每条边之后就开始从点1开始搜索,注意判断终止的时候,叶子节点的出度和入度一定是为1的,根据这个来终止;另外就是细节不要搞错就可以;

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,a[100005],ans,in[100005],out[100005];
bool vis[100005];
vector<ll>v[100005];
void dfs(ll u,ll cnt){
    if(a[u]) cnt++;else cnt=0;
    if(cnt>m) return;
    vis[u]=1;
    if(in[u]==1&&out[u]==1&&u!=1){
        vis[u]=1;
        ans++;return;
    }
    for(int i=0;i<v[u].size();i++){
        if(!vis[v[u][i]])
        dfs(v[u][i],cnt);
    }
}
int main(){
    //freopen("in.txt","r",stdin);
    scanf("%lld%lld",&n,&m);
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for(int i=1;i<n;i++){
        ll x,y;
        scanf("%lld%lld",&x,&y);
        v[x].push_back(y);
        v[y].push_back(x);
        in[x]++;out[y]++;
        in[y]++;out[x]++;
    }
    ans=0;
    dfs(1,0);
    printf("%lld\n",ans);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

killer_queen4804

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

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

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

打赏作者

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

抵扣说明:

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

余额充值