题解 | #Random Addition#

Random Addition

https://ac.nowcoder.com/acm/contest/57361/A

c题题解:

alt alt

#include<bits/stdc++.h>

using namespace std;

const int N = 1e6+100;

int a[N],b[N],f[N];//f[i]表示从b1到bi的异或和,特殊地,我们规定f[0]=0;
int num[30];//记录a1二进制表示上的各个位数
bool flag;//有没有出现矛盾的标记

int n,k,t;

signed main()
{
    cin>>t;
    while(t--)
    {
        flag=false;//初始化
        cin>>n>>k;
        f[0]=0;
        a[1]=0;
        for(int i=0;i<=29;i++)num[i]=-1;
        for(int i=1;i<=n-1;i++)
        {
            cin>>b[i];
            f[i]=f[i-1]^b[i];//求异或和
        }
        for(int i=0;i<n-1;i++)
        {
            if(flag)break;
            for(int j=29;j>=0;j--)
            {
                if((f[i]>>j&1)!=(f[i+1]>>j&1))//找到了不同位,进行比较
                {
                    if(num[j]==-1)
                    {
                        num[j]=(f[i]>>j&1);
                    }
                    else if(num[j]!=(f[i]>>j&1))
                    {
                        flag=true;//出现了矛盾,标记起来
                    }
                    break;//一但找到不同位,比较完之后直接退出
                }
            }
        }
        if(flag)
        {
            cout<<-1<<endl;
            continue;
        }
        k--;
        int s=0;//方案总数-1
        for(int i=29;i>=0;i--)if(num[i]==-1)s=s*2+1;
        if(s<k)//判断存不存在字典序第k小的方案
        {
            cout<<-1<<endl;
            continue;
        }
        int p=0;
        while(k)//将k拆成二进制,填充到a1的二进制表示中,已经确定的值保持不变
        {
            int x=k&1;
            while(num[p]!=-1)p++;
            num[p]=x;
            k = k >> 1;
        }
        for(int i=0;i<=29;i++)if(num[i]==-1)num[i]=0;//将剩下未填充的数位初始化为0
        for(int i=29;i>=0;i--)a[1]=a[1]*2+num[i];//计算a1,注意从最后一位开始算
        for(int i=2;i<=n;i++)a[i]=a[i-1]^b[i-1];//计算剩下的值
        if(a[n]>=pow(2,30))//判断序列A中是否存在大于等于2^30的数
        {
            cout<<-1<<endl;
            continue;
        }
        for(int i=1;i<=n;i++)cout<<a[i]<<" ";
        cout<<endl;
    }
}
全部评论
图片不能放大不能旋转,治好了我多年的颈椎病。
5 回复 分享
发布于 2023-08-07 17:43 湖南
Orz,直接就看懂了
2 回复 分享
发布于 2023-08-07 19:14 江西
这题太难写了
1 回复 分享
发布于 2023-08-07 17:22 上海
你怎么知道我歪着头看完的
1 回复 分享
发布于 2023-08-07 19:28 四川
建议图片旋转一下再发
1 回复 分享
发布于 2023-08-08 09:06 河南
%%%
点赞 回复 分享
发布于 2023-08-07 19:14 江西
妙啊
点赞 回复 分享
发布于 2023-08-07 19:31 四川
看懂了,谢谢
点赞 回复 分享
发布于 2023-08-07 21:55 福建
TQL
点赞 回复 分享
发布于 2023-08-08 10:27 安徽

相关推荐

2024-12-29 11:08
湖南工业大学 Java
程序员牛肉:简历没什么大问题了。 而且不要再换项目了。三月份就开暑期实习了,现在都一月份了。实在来不及重新开一下项目了。把一个项目写完或许很快,但是把一个项目搞懂吃透并不简单。所以不要换项目了,把你简历上面的两个项目好好挖一挖吧。 具体 体现在:你能不能流利的说出你的项目的每一个功能点代码实现?你能不能说出在这块除了A技术之外,还有其他技术能够实现嘛?如果有其他技术能够实现,那你这块为什么选择了你当前用的这个技术?
投递牛客等公司8个岗位
点赞 评论 收藏
分享
评论
28
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务