zoukankan      html  css  js  c++  java
  • 「CF1115」Microsoft Q# Coding Contest

    题目链接

    资料

    another 资料

    赛后题解

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

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

    G1. AND oracle

    Descripition

    给你 (N) 个量子位,若全为 (left|1 ight>) (即逻辑与结果为 (|1 angle)) 则翻转 (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

    Descripition

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

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

    注意到: (x_1igvee x_2igvee cdotsigvee x_n= eg( eg x_1igwedge eg x_2igwedgecdotsigwedge eg 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

    Descripition

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

    Solution

    即要验证 (p:forall iinleft[1,n ight],Xleft[i ight]=Xleft[n-i+1 ight]).

    我们发现若 (x=y) ,则 (CNOTleft(x,y ight)=left|0 ight>) .

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

    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

    Descripition

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

    Solution

    手模 (N=2) 的情况可以发现:

    [left|00 ight>mapstoleft|11 ight>,left|10 ight>mapstoleft|01 ight>,left|01 ight>mapstoleft|10 ight>,left|11 ight>mapstoleft|00 ight> ]

    所以只要翻转每一位就可以啦.

    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

    Descripition

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

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

    Solution

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

    再取几个数验证(暴露了我手玩的事实):

    [left|000 ight>mapsto frac{1}{2}left(left|000 ight>+left|100 ight>+left|001 ight>+left|101 ight> ight) ]

    [left|111 ight>mapsto frac{1}{2}left(left|010 ight>+left|110 ight>+left|011 ight>+left|111 ight> ight) ]

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

    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

    Descripition

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

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

    Solution

    其实思路很简单.

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

    考试的时候没有做出来.

    写了一个假的程序QAQ.

    仿佛是对的?

    然而一直 (WA) (1).

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

    自闭了.

    赛后

    原来有 Controlled 这种操作.

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

    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) 神仙.

    果然我还是太蒻了啊

    弃坑了.

  • 相关阅读:
    739. Daily Temperatures
    535. Encode and Decode TinyURL
    811. Subdomain Visit Count
    706. Design HashMap
    C++-static作用(转)
    大学四年应当如何渡过(转)
    计算机导论第八章-总结
    计算机导论第四章习题
    计算机导论-第一章习题
    20世纪最伟大的十大算法
  • 原文地址:https://www.cnblogs.com/realSpongeBob/p/CF1115.html
Copyright © 2011-2022 走看看