[2017.11.25]verlauf

本文介绍了一种将特定形式的复数转换为基于复数r=(-1+√7i)/2的表示方法。通过分析复数的性质及归纳证明,提出了一种有效的算法来找出将复数x+y√7i转换为r进制表示时,每一位上为1的位置所构成的整数集合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

虽然我只过了95分但是还要写个题解,说不定什么时候RP好就A了,O(∩_∩)O哈哈~。

题面

一个神奇的复数 r=1+7i2,其中 i 是虚数单位 i2=1。 对于任意整数x 和 y,
我们都可以找到⼀个有限的整数集合 S 使得

x+y7i=kSrk

换句话说,我们将 x + y √7 i 转换为 r 进制,每位上是 0 或者 1。其中为 1的位置的集合记做 S 。
输入x 和y,从小到大输出集合 S 中的元素,可以证明 S 是唯一的。 集合中不能包含相同元素。

输入格式

一行两个整数表示 x, y。

输出格式

一行一个数组表示集合 S ,从小到大输出。

样例输入

7 1

样例输出

2 3 4 5 6 7

数据范围与提示

对于 100% 的数据,满足 |x|,|y|1018

对于 50% 的数据,满足 y=0

对于 50% 的数据,满足 |x|,|y|102

以上两部分数据相交 25%。

思路

找规律,打一个rk的表,写个程序试试。

程序如下:

#include<algorithm>
#include<cmath>
#include<complex>
using namespace std;
typedef complex<double> cd;

#include<stdio.h>
#include<stdlib.h>

const cd r=cd(-1.0,sqrt(7.0))/2.0;

int main(){
    cd rk(1,0);
    for(int i=0;i<=15;i++){
        printf("%5d:  ",i);
        printf("(%g + %g sqrt(7))/2\n",rk.real()*2,rk.imag()*2.0/sqrt(7.0));
        rk*=r;
    }
    return 0;
}

运行结果:

    0:  (2 + 0 sqrt(7))/2
    1:  (-1 + 1 sqrt(7))/2
    2:  (-3 + -1 sqrt(7))/2
    3:  (5 + -1 sqrt(7))/2
    4:  (1 + 3 sqrt(7))/2
    5:  (-11 + -1 sqrt(7))/2
    6:  (9 + -5 sqrt(7))/2
    7:  (13 + 7 sqrt(7))/2
    8:  (-31 + 3 sqrt(7))/2
    9:  (5 + -17 sqrt(7))/2
   10:  (57 + 11 sqrt(7))/2
   11:  (-67 + 23 sqrt(7))/2
   12:  (-47 + -45 sqrt(7))/2
   13:  (181 + -1 sqrt(7))/2
   14:  (-87 + 91 sqrt(7))/2
   15:  (-275 + -89 sqrt(7))/2

惊奇的发现:当rk 被表示成 a+b7i2 时,其中的ab 的和一定是四的倍数,不妨用归纳法证明一下。

定义命题P(x) 表示rx=a+b7i2:a,bZa+b0mod4

首先,P(1):1+17i2a=1,b=1 显然成立。

P(x) 成立时有 rx=a+b7i2:a,bZa+b0mod4

那么:

rx+1=rxr=a+b7i2×1+7i2=a7b2+ab27i2

所以:

P(x+1)a7b2+ab2=4b(bZ)4b0mod4

由此可得P(x):xN 均成立。

也可以顺便证得另一个结论:

c=a+b7i2(a,bZ),cr=a7b2+ab27i2real(cr)+imag(cr)=4b0mod4

↑这个结论后文中会用到。

假设max(S)n ,用Si 表示集合S中从小到大数第i个元素(i大于元素总个数,令Si=0)。

再定义一个数列A1..n 满足

Ax={0:xS1:xS

则有:

x+y7i=kSrk=k=0nAkrk

该式可以看成是一个关于r的n次多项式,可用秦九韶算法进行处理。

k=0nAkrk=((...(((Anr)+An1)r+An2)r+...)r+A1)r+A0

先分析A0 的值是多少,此时q=2x+2y7i2 ,若2x+2y0mod4 ,证明A0=1(因为它表示不成r的c倍的形式,c的定义见上文。)而当2x+2y0mod4,不难发现一定有 A0=0 成立,证明如下:

假设A0=1,那么有:

q=2x+2y7i2=((...(((Anr)+An1)r+An2)r+...)r+A1)r+1

所以:

q1=2(x1)+2y7i2=((...(((Anr)+An1)r+An2)r+...)r+A1)r

又因为:

x,y2x+2y0mod4

所以:

2(x1)+2y20mod4

即:q1 不能表示成 cr 的形式,显然与:

q1=((...(((Anr)+An1)r+An2)r+...)r+A1)r

矛盾。

所以A0=0充要得证。

分析完A0 我们将q减去A0 再除以r ,现在A1 和刚才的A0 就出在了完全相同的地位了,可以同理得出。直到一个时刻q=0,说明这个多项式已经被满足,结束运算即可。

代码

附上95分代码:

#include<stdio.h>
#include<stdlib.h>

struct complex{
    long long real,imag;
};
typedef struct complex complex;

#define DEBUG (0)
#define debug   if(DEBUG)
#define runtime if(!DEBUG)

int main(){
    runtime{
        freopen("verlauf.in","r",stdin);
        freopen("verlauf.out","w",stdout);
    }
    long long x,y;
    scanf("%lld%lld",&x,&y);
    x*=2;y*=2;
    debug{
        printf("x=%lld y=%lld\n",x,y);
    }
    int i;
    for(i=0;!(x==0 && y==0);i++){
        debug printf("i=%d x=%lld y=%lld\n",i,x,y);
        if((x+y)%4!=0){//has value
            runtime printf("%d ",i);
            debug printf("[%d] ",i);
            x-=2;
        }
        long long nx=(7*y-x)/4;
        long long ny=(-x-y)/4;
        x=nx;y=ny;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值