标签:gcd ++ item ret str reg code ges int
你有一台超小的电脑,内存只有两个寄存器:X和Y。寄存器只能存储正整数,一开始两个寄存器的值都是1,电脑操作系统只有两种指令:指令[X]和指令[Y]。
指令[X]的功能是:X ← X + Y,即把两寄存器目前的值累加到X寄存器;
指令[Y]的功能是:Y ← X + Y,即把两寄存器目前的值累加到Y寄存器。例如:指令序列"XXYYX"的执行过程如下:
可以发现,执行指令序列"XXYYX"后,X寄存器的值是10,Y寄存器的值是7。现在你的任务是:给你一个正整数R, 你要编写指令序列,使得最后X寄存器的值是R (此时Y寄存器可以是任意整数). 当然,我们希望你编写的指令序列的长度要尽量短,在此前提下,如果有多种方案,请输出字典序最小的一种方案。
多组测试数据。
第一行,一整正整数G,表示有G组测试数据,1 <= G <=5
每组测试数据格式:
一个正整数R,其中 1 <= R <= 1000000。
一个字符串,代表生成R的长度最短的指令序列。
4
10
3
20
34
XXYYX
XX
XYYYYXX
XYXYXYX
搜索貌似会爆,仔细观察,可以发现这其实就是进行更相减损法的过程,那么枚举x来模拟更相减损法即可。
#include <iostream> #include <cstdio> using namespace std; int G; int r; int len; char ans[1000005]; int tl; char s[1000005]; void Judge(int x, int y) //gcd { tl = 0; while(x != y && tl <= len) { if(x > y) { x -= y; s[++tl] = ‘X‘; } else { y -= x; s[++tl] = ‘Y‘; } } if(x != 1 || tl > len) return; if(s[tl] == ‘Y‘) { for(register int i = tl; i; --i) { if(s[i] == ‘X‘) s[i] = ‘Y‘; else s[i] = ‘X‘; } } if(tl == len) { int f = 0; for(register int i = tl; i; --i) { if(ans[tl - i + 1] < s[i]) { f = 1; break; } else if(ans[tl - i + 1] > s[i]) { break; } } if(f) return; } len = tl; for(register int i = tl; i; --i) { ans[tl - i + 1] = s[i]; } return; } int main() { scanf("%d", &G); while(G--) { scanf("%d", &r); len = 2147483647; if(r == 1) { putchar(‘\n‘); continue; } else if(r == 2) { printf("X\n"); continue; } for(register int i = 1; i + i < r; ++i) { Judge(i, r - i); } ans[len + 1] = 0; printf("%sX\n", ans + 1); } return 0; }
标签:gcd ++ item ret str reg code ges int
原文地址:https://www.cnblogs.com/kcn999/p/10585679.html