总结 | #寒假第四场

C. 墨提斯的排列


考点:格雷码,二进制运算

题意:构造一个长度为2的n次方的排列,使得相邻两项异或值异或值之和最小

为什么错?弄错了规律(规律就是相邻两个数二进制码只能相差一个1,且出现不同的地方越低位越好,反正就是没找到这个规律,然后格雷码刚好符合这个规律)

AC代码
//格雷码做法
void whale_solve(){
    int n;cin>>n;
    int N=1<<n;
    vector<int>a(N);
    for(int i=0;i<N;i++) a[i]=i;
    for(int i=0;i<N;i++) cout<<(a[i]^(a[i]>>1))<<" ";
}
//不懂格雷码的做法
void whale_solve(){
    int n;cin>>n;
    vector<int>p={0};
    for(int i=0;i<n;i++){
        int add=1<<i;
        for(int j=p.size()-1;j>=0;j--) p.push_back(p[j]+add);
    }
    for(int i=0;i<p.size();i++) cout<<p[i]<<" ";
}

当 n=0 时:序列 = [0]

当 n=k 时:序列 = [G(k-1), reverse(G(k-1)) + 2^{k-1}]

//n=1->0,1
初始: p = [0]
i=0: add = 1<<0 = 1
倒序遍历 p: j=0 → p[0]=0 → 添加 0+1=1
结果: p = [0, 1]

//n=2->0,1,3,2
初始: p = [0, 1]  (n=1的结果)
i=1: add = 1<<1 = 2
倒序遍历 p:
  j=1: p[1]=1 → 添加 1+2=3
  j=0: p[0]=0 → 添加 0+2=2
结果: p = [0, 1, 3, 2]

//n=3->0,1,3,2,6,7,5,4
初始: p = [0, 1, 3, 2]
i=2: add = 1<<2 = 4
倒序遍历 p:
  j=3: p[3]=2 → 添加 2+4=6
  j=2: p[2]=3 → 添加 3+4=7
  j=1: p[1]=1 → 添加 1+4=5
  j=0: p[0]=0 → 添加 0+4=4
结果: p = [0, 1, 3, 2, 6, 7, 5, 4]

可以发现:排列以一对递增(相差1),一对递减(相差1)的规律组成,并以一种特殊的镜像呈现出来,这正是j逆序循环的原因。

H. 时不时使使用玉米加农炮掩饰害羞的邻座艾莉同学


考点:STL,暴力

题意:单点修改,区间查询最大值,具体背景看原题。

为什么错?不懂如何维护最大值,觉得可能会超时

AC代码
using ll=long long;

void whale_solve(){
    int n,m,q;cin>>n>>m>>q;
    vector<vector<ll>>sum(n+1,vector<ll>(m+1,0));
    array<ll,3>ma={0,0,0};//最大值数组
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            int a;cin>>a;
            for(int dx=-2;dx<=2;dx++){
                int k=2-abs(dx);//循环范围
                for(int dy=-k;dy<=k;dy++){
                    int x=i+dx,y=j+dy;
                    if(x<1||y<1||x>n||y>m) continue;//超出范围跳过
                    sum[x][y]+=a;//记录每个点范围内的总和
                    ma=max(ma,{sum[x][y],x,y});//维护最大值和位置
                }
            }
        }
    }
    while(q--){
        int x,y,z;cin>>x>>y>>z;
        for(int dx=-2;dx<=2;dx++){
            int k=2-abs(dx);
            for(int dy=-k;dy<=k;dy++){
                int xx=x+dx,yy=y+dy;
                if(xx<1||yy<1||xx>n||yy>m) continue;
                sum[xx][yy]+=z;
                ma=max(ma,{sum[xx][yy],xx,yy});
            }
        }
        cout<<ma[1]<<" "<<ma[2]<<"\n";
    }
}

全部评论

相关推荐

明明就不饿:看不懂你到底会啥,什么岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务