「CF1115」Microsoft Q# Coding Contest - Winter 2019 - Warmup

题目链接

资料

another 资料

赛后题解

神仙 \(LMOliver\) 叫来一起做这套题被吊起来打.

毕竟量子计算什么的,只有神仙才会.我太蒻了.

G1. AND oracle

Intention

给你 \(N\) 个量子位,若全为 \(\left|1\right>\) (即逻辑与结果为 \(|1\rangle\)) 则翻转 \(y\) ,否则什么也不做.

Solution

开始被这道题卡了好久.

只知道 X,H,CNOT,CCNOT 四个操作,硬是用这些操作搞出来了.

具体方法就是用分治把原问题分成两边递归求解.

Code

namespace Solution {
    open Microsoft.Quantum.Primitive;
    open Microsoft.Quantum.Canon;

    operation Solve (x : Qubit[], y : Qubit) : Unit {
        body (...) {
            let N = Length(x);
            if (N == 0) {
                X(y);
            } elif (N == 1) {
                CNOT(x[0], y);
            } elif (N == 2) {
                CCNOT(x[0], x[1], y);
            } else {
                using (LMO = Qubit()) {
                    using (QY = Qubit()) {
                        let mid = N / 2;
                        Solve(x[0 .. mid - 1], LMO);
                        Solve(x[mid .. N - 1], QY);
                        CCNOT(LMO, QY, y);
                        Solve(x[0 .. mid - 1], LMO);
                        Solve(x[mid .. N - 1], QY);
                    }
                }
            }
        }
        adjoint auto;
    }
}

然而,题解中只有一行(naive的我并不会Controlled门).

OR oracle

Intention

给你 \(N\) 个量子位,若存在一位为 \(\left|1\right>\) (即逻辑或结果为 \(|1\rangle\)) 则翻转 \(y\) ,否则什么也不做.

有了上一题的基础,这题应该很容易了.

注意到: \(x_1\bigvee x_2\bigvee \cdots\bigvee x_n=\neg(\neg x_1\bigwedge\neg x_2\bigwedge\cdots\bigwedge\neg x_n)\) (De Morgan’s laws)

所以只要先将每一位翻转,再进行第一题的步骤,最后再将结果翻转即可.

Code

namespace Solution {
    open Microsoft.Quantum.Primitive;
    open Microsoft.Quantum.Canon;

    operation Zyy (x : Qubit[], y : Qubit) : Unit {
        body (...) {
            let N = Length(x);
            if (N == 0) {
                X(y);
            } elif (N == 1) {
                CNOT(x[0], y);
            } elif (N == 2) {
                CCNOT(x[0], x[1], y);
            } else {
                using (LMO = Qubit()) {
                    using (QY = Qubit()) {
                        let mid = N / 2;
                        Zyy(x[0 .. mid - 1], LMO);
                        Zyy(x[mid .. N - 1], QY);
                        CCNOT(LMO, QY, y);
                        Zyy(x[0 .. mid - 1], LMO);
                        Zyy(x[mid .. N - 1], QY);
                    }
                }
            }
        }
        adjoint auto;
    }

    operation Solve (x : Qubit[], y : Qubit) : Unit {
        body (...) {
            let N = Length(x);
            for (i in 0 .. N - 1) {
                X(x[i]);
            }
            Zyy(x[0 .. N - 1], y);
            X(y);
            for (i in 0 .. N - 1) {
                X(x[i]);
            }
        }
        adjoint auto;
    }
}

然而题解只有两行......

G3. Palindrome checker oracle

Intention

给你 \(N\) 个量子位,判断其是否回文.

Solution

即要验证 \(p:\forall i\in\left[1,n\right],X\left[i\right]=X\left[n-i+1\right]\).

我们发现若 \(x=y\) ,则 \(CNOT\left(x,y\right)=\left|0\right>\) .

所以只要用后半段 CNOT 前半段,再判断是否全为 \(\left|0\right>\) 即可.

Code

namespace Solution {
    open Microsoft.Quantum.Primitive;
    open Microsoft.Quantum.Canon;

    operation Make (x : Qubit[], y : Qubit) : Unit {
        body (...) {
            let N = Length(x);
            if (N == 0) {
                X(y);
            } elif (N == 1) {
                CNOT(x[0], y);
            } elif (N == 2) {
                CCNOT(x[0], x[1], y);
            } else {
                using (LMO = Qubit()) {
                    using (QY = Qubit()) {
                        let mid = N / 2;
                        Make(x[0 .. mid - 1], LMO);
                        Make(x[mid .. N - 1], QY);
                        CCNOT(LMO, QY, y);
                        Make(x[0 .. mid - 1], LMO);
                        Make(x[mid .. N - 1], QY);
                    }
                }
            }
        }
        adjoint auto;
    }

    operation Solve (x : Qubit[], y : Qubit) : Unit {
        body (...) {
            let N = Length(x);
            let mid = N / 2;
            for (i in 0 .. mid - 1) {
                CNOT(x[N - i - 1], x[i]);
            }
            for (i in 0 .. mid - 1) {
                X(x[i]);
            }
            Make(x[0 .. mid - 1], y);
            for (i in 0 .. mid - 1) {
                X(x[i]);
            }
            for (i in 0 .. mid - 1) {
                CNOT(x[N - i - 1], x[i]);
            }
        }
        adjoint auto;
    }
}

U1. Anti-diagonal unitary

Intention

要求对 \(N\) 个量子比特进行操作,使得效果与乘了一个对角线均不为 \(0\) 的矩阵等同.

Solution

手模 \(N=2\) 的情况可以发现:
\[
\left|00\right>\mapsto\left|11\right>,\left|10\right>\mapsto\left|01\right>,\left|01\right>\mapsto\left|10\right>,\left|11\right>\mapsto\left|00\right>
\]
所以只要翻转每一位就可以啦.

Code

namespace Solution {
    open Microsoft.Quantum.Primitive;
    open Microsoft.Quantum.Canon;

    operation Solve (qs : Qubit[]) : Unit {
        for (q in qs) {
            X(q);
        }
    }
}

U2. Chessboard unitary

Intention

要求对 \(N\) 个量子比特进行操作,使得效果与乘了一个如下形状的矩阵等同.

XX..XX..
XX..XX..
..XX..XX
..XX..XX
XX..XX..
XX..XX..
..XX..XX
..XX..XX

Solution

手模观察矩阵的性质可以发现,原矩阵的变换相当于第二位不变,其余每一位变为了叠加态.

再取几个数验证(暴露了我手玩的事实):
\[
\left|000\right>\mapsto \frac{1}{2}\left(\left|000\right>+\left|100\right>+\left|001\right>+\left|101\right>\right)
\]
\[
\left|111\right>\mapsto \frac{1}{2}\left(\left|010\right>+\left|110\right>+\left|011\right>+\left|111\right>\right)
\]

发现糊的结论并没有错误.

Code

namespace Solution {
    open Microsoft.Quantum.Primitive;
    open Microsoft.Quantum.Canon;

    operation Solve (qs : Qubit[]) : Unit {
        let N = Length(qs);
        for (i in 0 .. N - 1) {
            if (i != 1) {
                H(qs[i]);
            }
        }
    }
}

U3. Block unitary

Intention

要求对 \(N\) 个量子比特进行操作,使得效果与乘了一个如下形状的矩阵等同.

.X..
X...
..XX
..XX

Solution

其实思路很简单.

若最后一位为 \(\left|1\right>\) 则对其余每一位进行 H 操作,否则进行 X 操作.

考试的时候没有做出来.

写了一个假的程序QAQ.

仿佛是对的?

然而一直 \(WA\) \(1\).

\(LMOliver\) 神仙说我的写法会造成量子纠缠 \(QAQ\).

自闭了.

赛后

原来有 Controlled 这种操作.

可以用一个量子位的状态是否为 \(\left|1\right>\) 来控制是否进行操作......

Code

namespace Solution {
    open Microsoft.Quantum.Primitive;
    open Microsoft.Quantum.Canon;

    operation Solve (qs : Qubit[]) : Unit {
        let N = Length(qs);
        for (i in 0 .. N - 2) {
            Controlled H(qs[N - 1 .. N - 1], qs[i]);
            X(qs[N - 1]);
            Controlled X(qs[N - 1 .. N - 1], qs[i]);
            X(qs[N - 1]);
        }
    }
}

后记

\(\%\%\%LMOliver\) 神仙.

果然我还是太蒻了啊

弃坑了.

原文地址:https://www.cnblogs.com/realSpongeBob/p/10482822.html

时间: 2024-10-08 09:20:42

「CF1115」Microsoft Q# Coding Contest - Winter 2019 - Warmup的相关文章

「2014-5-31」Z-Stack - Modification of Zigbee Device Object for better network access management

写一份赏心悦目的工程文档,是很困难的事情.若想写得完善,不仅得用对工具(use the right tools),注重文笔,还得投入大把时间,真心是一件难度颇高的事情.但,若是真写好了,也是善莫大焉:既可让人明白「为何如此设计」,即「知其然更知其所以然」:也能剥离一些琐碎的细节,让更多没那么多时间与精力.或者背景知识不足的朋友,对核心方法和思路,多一点理解,即,给人提供一种「纲举目张提纲挈领抽丝剥茧」的可能性. 机缘巧合,俺今天就决定抛砖引玉,写一篇不那么好的工程文档.也期望对本文话题感兴趣的朋

LibreOJ #2016. 「SCOI2016」美味

二次联通门 : LibreOJ #2016. 「SCOI2016」美味 /* LibreOJ #2016. 「SCOI2016」美味 dalao们都在说这题如果没有加法balabala就可以用可持久化trie解决了 然而我连那个也不会啊QAQ 此题用主席树 从高位到低位贪心 能填1就填1,也就是查询一段区间有没有某个范围的数 (然而由乃dalao说可持久化线段树和可持久化trie是一个东西) */ #include <cstdio> #include <iostream> #inc

LibreOJ #2061. 「HAOI2016」放棋子

二次连通门 : LibreOJ #2061. 「HAOI2016」放棋子 /* LibreOJ #2061. 「HAOI2016」放棋子 MDZZ ... 错排 + 高精 */ #include <iostream> #include <cstdio> #include <vector> #include <iomanip> #include <cassert> #include <algorithm> #define int64 l

程序员「奇葩」说

一直以来「奇葩」这个词都是偏贬义的,直到去年有个综艺节目叫「奇葩说」挺热闹,这里的人不一定是奇葩,更多指达人的意思. 「奇葩说」里的达人都是能说会道的,我的主业是程序员,所以只能写写在我职业生涯中碰到的一些「奇葩」程序员. 你懂的,我这里的「奇葩」没有任何贬义的意思. 月在胸襟人在途 我刚入行时的第一位项目经理,70后.那年三十出头,在银行客户现场做项目经理,负责一个二十来人的客户现场团队. 虽然他的职位是项目经理,但实际那时他真是一名地道的资深程序员. 70 后的程序员大都是从写 C 开始的,

AC日记——「SCOI2015」国旗计划 LiBreOJ 2007

#2007. 「SCOI2015」国旗计划 思路: 跪烂Claris 代码: #include <cstdio> #include <algorithm> #define maxn 800010 int n,m,ai[maxn][2],bi[maxn],f[maxn<<1],st[maxn]; int g[maxn],nxt[maxn<<1],q[maxn<<1],t,ans[maxn],L,x,y,i; inline void in(int&a

LibreOJ #2013. 「SCOI2016」幸运数字

二次联通门 : LibreOJ #2013. 「SCOI2016」幸运数字 /* LibreOJ #2013. 「SCOI2016」幸运数字 树链剖分 + 线段树 + 线性基合并 没什么可说的 对原树进行树链剖分 然后建线段树 每个区间维护一段线性基 每次暴力把一段插入另一段中 最后线性基求最大即可 注意线性基求最大时一定是倒着枚举的 */ #include <cstdio> #include <iostream> const int BUF = 12312334; char Bu

TYVJ2032 「Poetize9」升降梯上

P2032 「Poetize9」升降梯上 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 开启了升降梯的动力之后,探险队员们进入了升降梯运行的那条竖直的隧道,映入眼帘的是一条直通塔顶的轨道.一辆停在轨道底部的电梯.和电梯内一杆控制电梯升降的巨大手柄. Nescafe之塔一共有N层,升降梯在每层都有一个停靠点.手柄有M个控制槽,第i个控制槽旁边标着一个数Ci,满足 C1<C2<C3<……<CM.如果Ci>0,表示手柄扳动到该槽时,电梯将

零元学Expression Blend 4 - Chapter 11 用实例了解布局容器系列-「Border」

原文:零元学Expression Blend 4 - Chapter 11 用实例了解布局容器系列-「Border」 将教大家以实做案例认识Blend 4 的布局容器,此章介绍的布局容器是Blend 4 里的专情王子-「Border」. ? ? 本系列将教大家以实做案例认识Blend 4 的布局容器,此章介绍的布局容器是Blend 4 里的专情王子-「Border」. ? ? 就是要让不会的新手都看的懂! ? <专情王子?查理B> Border是Blend里最简单的布局容器,可以使用Borde

零元学Expression Blend 4 - Chapter 8 用实例了解布局容器系列-「Grid」

原文:零元学Expression Blend 4 - Chapter 8 用实例了解布局容器系列-「Grid」 本系列将教大家以实做案例认识Blend 4 的布局容器,此章介绍的是Blend 4 里的布局容器大哥-「Grid」. ? 本系列将教大家以实做案例认识Blend 4 的布局容器,此章介绍的是Blend 4 里的布局容器大哥-「Grid」. ? ? ? 就是要让不会的新手都看的懂! ? ? ? <实至名归的容器大哥> Blend 4内的容器有很多种,比较常运用到的除了有Grid.Can