双六(扩展欧几里得算法)a
1,双六是一个类似于大富翁的游戏。奇奇怪怪。
2,如何搞懂这些屁东西。还是得用我的老套路。
3,
#include<iostream> #include<algorithm> using namespace std; int extgcd(int a,int b,int& x,int& y) { int d=a; if(b!=0) { d=extgcd(b,a%b,y,x); y-=(a/b)*x; } else { x=1; y=0; } return d; } int main(){ int a,b,x,y; int cnt[4]={0}; cin>>a>>b; if(extgcd(a,b,x,y)!=1) { cout<<"-1"<<endl; return 0; } if(x>0) cnt[0]=x; else if(x<0) cnt[2]=-x; if(y>0) cnt[1]=y; else if(y<0) cnt[3]=-y; for(int i=0;i<4;i++) cout<<cnt[i]; cout<<endl; return 0; }
4,为啥这都有些长。
x,y啥都没有为啥能弄进去呢。
先得背代码的阶段是否可以进化?
5,双向传递。反正就是这个意思。
6,扩展欧几里得算法的核心。
int extgcd(int a,int b,int& x,int& y) { int d=a; if(b!=0) { d=extgcd(b,a%b,y,x); y-=(a/b)*x; } else { x=1; y=0; } return d; }
7,模拟代码失败了。因为没有X,Y的确切值来看。
gcd(a,b)可以表示为a和b最小的正线性组合
1、int; int是C++关键字,表示整型,其大小是32位有符号整型,表示的范围是-2,147,483,648 到 2,147,483,647;在声明和定义变量时使用,它表示的意思是所声明或所定义的变量为整型变量。 如果其用于函数参数时,其传递方向为值传递,即只能将实参的值传递给形参,而不能将 形参的值传递给实参。 例如:通过这种方式去进行交换两个数是无法达到目的的。 例子1: #include<iostream> using namespace std; voidswap1(inta,intb) { inttmp; tmp = a; a = b; b = tmp; } int main(){ inta = 1; intb = 2; swap1(a, b); cout<<"a = "<<a<<endl; cout<<"b = "<<b<<endl; system("pause"); return0; } 结果为:a=1 b=2 因为传递的方式为值传递(单向传递); 2、int&; 这里的&不是取地址符号,而是引用符号,引用是C++对C的一个重要补充。变量的引用就是 变量的别名,讲的通俗一点就是另外一个名字,比如:“张三这个人在家里,老爸老妈叫他 三娃子,那么这个三娃子就是指张三这个人,如果叫张三去做某事,就是叫三娃子去做某事, 这两个名字指的是同一个人。”同样可以理解如果变量b是变量a的引用 那么无论a,b中任 何一个值改变,另外一个也相应的改变,在声明一个引用时,必须同时使之初始化,即声 明它代表哪一个变量。请注意:由于引用不是独立的变量,编译系统不给它单独分配存 储单元,因此在建立引用时只有声明没有定义,只是声明它与原有的某一变量的关系。 在声明一个变量的引用后,在本函数执行期间,该引用一直与其代表的变量相联系,不能 再作为其他变量的别名。说得简单点:张三和三娃子是指同一个人,不能李四也叫三娃子, 如果可以这样,叫三娃子去做什么,是叫李四呢还是张三呢,这就会乱套了。所以在C++中 一个引用变量只能对应一个原始的变量,不能对应两个或多个原始的变量; 下面简单说明引用: a)声明引用时必须指定它代表的是哪一个变量,即对它初始化。 int &a=b;这样是声明a是变量b的引用 如果是int &a;这样就是错的,没有指定a代表哪一个变量。 b)引用与其所代表的变量共享同一内存单元,系统并不为引用另外分配存储单元; 这个应该好理解;就像前面所说的,张三和三娃子都是同一个人,三娃子只是张三的别名。 因此,对于 int &a=b;这个例子来说,要输出a和b 的地址,肯定是相同的。 c)怎样区分&是引用还是取地址符呢?方法是:判断&a这样的形式前是否有类型符即 int &a=b;如果有类型符(int)则是引用,否则是取地址运算符。 d)对引用的初始化,可以是一个变量名,也可以是另一个引用。 换句话说:张三的别名可以是三娃子,三小子……及其他多个别名 而三娃子也可以有其他的别名,比如说:老三,小三等 用程序可以这样: int a=1; //这里是定义一个整形变量 int &b=a;//声明b是整型变量a的别名 int &c=b;//声明c是整型引用变量b的别名 int &d=a;//声明d是整型变量a的别名 e)引用初始化后不能再被重新声明为另一变量的别名 即三娃子既然是指张三这个人,就不能让其他人也叫三娃子 即一个别名只能对应一个原始变量,但是一个原始变量可以有多个别名,而且别名也可以 由自己的别名。 C++中增加引用主要是作为函数参数,进行数据传递的功能; 我们知道如果用变量名作为实参,其传递方向是单向的,而用引用作为实参其传递方向 是双向的; 也许你会问,在c语言中不是有指针吗,用指针进行参数传递不也是双向的吗?其实其 本质上也是值传递,只不过是将变量的地址传给指针,通过指针获取变量的值,这样做 虽能得到结果,但通过指针运算符去访问有关变量,比较麻烦。 下面分析一下使用引用和使用指针变量作为函数形参的不同(以例子1中的swap函数为例): 1、如果使用引用,则不必在swap函数设立指针变量,指针变量要另外开辟内存单元,其 内容是地址。而引用不是一个独立的变量,并不占用内存单元 2、在main函数中调用swap函数时实参不必再变量名前加&以表示地址,系统传递的是 实参的地址不是实参的值。 3、使用指针变量时,为了表示指针变量所指向的变量,必须使用指针运算符*,而使用 引用时,引用就代表该变量,不必使用指针运算符*; 4、用引用完成的工作,用指针也能完成。但引用比指针的使用直观、方便,直截了当, 不必“兜圈子”,容易理解。有些过去只能用指针来处理的问题,现在可以用引用来代替, 从而降低了程序设计的难度。 对引用进一步说明: 1、不能建立void类型的引用。 因为任何实际存在的变量都是属于非void类型的,void的含义是无类型或空类型, void只是在语法上相当于一个类型而已。 2、不能建立引用的数组。 如:char c[6]="hello"; char &rc=c;//错误 因为数组名是数组首元素的地址,本身不是一个占有存储空间的变量。 3、可以将变量的引用的地址赋给一个指针,此时指针指向的是原来的变量。 这句话可以这样说:将引用变量的地址赋给一个指针,此时指针指向的是引用变量, 相当于指向原来的变量 int a=2; int &b=a;//这个声明语句中的&是一个引用 int *p=&b;//这个指针初始化语句中的&是取地址运算符 上面一行等价于 int *p=&a; 但是不能定义指向引用类型的指针变量,不能写成 int & *p=&a;//企图定义指向引用类型的指针变量p,错误 因为引用不是一种独立的数据类型,因此不能建立指向引用类型的指针变量。 4、可以建立指针变量的引用如 int i=5; int *p=&i; int * &pt=p;//建立指针变量p的引用pt 引用变量pt代表一个int *类型的数据对象(即指针变量) 5、可以用const对引用加以限定,不允许直接改变该引用的值,但是可以改变原 变量的值去改变引用的值; int i=5; const int &a=i; a=3;//错误,因为引用a是const int 类型不能直接改变引用的值 但是可以这样修改: i=3; 此时输出i和a都是3 6、可以用常量或表达式对引用进行初始化,但此时必须用const作声明。 int i=5; const int &a=i+1; 此时编译系统是这样处理的:生成一个临时变量,用来存放该表达式的值,引用是 该临时变量的别名、系统将“const int &a=i+1;”转换为 int temp=i+1; const int &a=temp; 临时变量是在内部实现的,用户不能访问临时变量; 用这种办法不仅可以用表达式对引用进行初始化,还可以用不同类型的变量对之 初始化;如 double d=3.1415926; const int &a=d; 以上等价为: double d=3.1415926; int temp=d; const int &a=temp; 如果在上面不用const则会发生错误 double d=3.1415926; int &a=d;//未加const,错误 为什么?因为如果可以这样做,那么修改引用a的值(如a=3.56),则临时变量temp的值也 变为3.56,即修改了临时变量temp的值,但不能修改变量d的值,这往往不是用户所希望 的,即存在二义性。与其允许修改引用的值而不能实现用户的目的,还不如不允许修改 引用的值。这就是C++规定对这类引用必须加const的原因。