题意:

给一个数对 \((a,b)\) ,每次可以进行操作 \((a,b) \to (|a-b|,b)\) 或 \((a,b) \to (a,∣a−b∣)\),问最后能否令 \(a=x\) 或 \(b=x\)

分析:

题目中出现了状态之间的转换,我们不妨装模做样地来一个状态分析(尽管这是个数论题)。

首先,令 \(a\) 远远大于 \(b\),可以得到:

            \((a,b)\to(a-b,b)\) 或 \((a,b)\to(a,a-b)\)

\[(a,a-b) \to (b,a-b) 或(a,b)
\]

观察这个柿子的转移结果,不难发现,他跟之前所得到的是等价的。

\[(a-b,b)\to(a-b-b,b)或(a-b,a-b-b)
\]

同理,在这个式子里面,只有转移结果左边的那个柿子才能继续向外转移。

综上,可以发现,在本题中,数对总是会这样转移:\((a,b)\to (a-b-b-...,b)\)。自然,当前一项小于后一项时,交换并继续处理,这就很像欧几里得算法了!

AC代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int a,b,c;
void Swap(int &a,int &b){
int c = a;
a = b;
b = c;
}
bool check(int a,int b,int c){
if(a < b){
swap(a,b);//交换
}
if(a == c || b == c)return 1;//假如两个数中有任意一个数等于给出的数,那么目标已经达到,返回true
if(!a || !b)return 0;
if(c > a)return 0;//如果当前处理到的最大值已经小于目标值,那么就不可能达到,返回false
if(a % b == c % b)return 1;
return check(a % b,b,c);
}
int t;
signed main(){
cin >> t;
while(t--){
cin >> a >> b >> c;
bool flag = check(a,b,c);
if(flag)cout << "YES\n";
else cout << "NO\n";
} }

最新文章

  1. AmazeUI 框架知识点-元素
  2. Rails : 产品环境(生产环境)的部署
  3. 浅析tomcat nio 配置
  4. github 添加项目
  5. poj-1703-Find them, Catch them
  6. 泛函编程(19)-泛函库设计-Parallelism In Action
  7. POJ 1611 The Suspects (并查集)
  8. winForm 打印预览
  9. 8个开发必备的PHP功能(转)
  10. Spark学习计划
  11. MYSql和PHP计算数据性能
  12. ecshop广告调用方法
  13. 使用 ConfigSource 特性 拆分 Web.config 文件
  14. “字符串替换” 和 “模板设置” (application/config.php)
  15. CodeForces - 710F:String Set Queries (二进制分组 处理 在线AC自动机)
  16. css radial-gradient()函数用法
  17. loadrunner 接口性能脚本编写(Get请求和Post请求)
  18. .net 环境配置
  19. 判断二叉树B是否是树A的子树
  20. android GridView的setOnItemClickListener事件不执行

热门文章

  1. 北航内核操作系统-lab1
  2. 移动端input的disabled属性对字体颜色影响
  3. sklearn机器学习-特征提取1
  4. 通过有序线性结构构造AVL树
  5. for循环+数字类型补充
  6. zabbix脚本获取web status code,异常告警
  7. spring boot 默认日志替换为 log4j
  8. Helloworld 驱动模块加载
  9. 『忘了再学』Shell基础 — 17、预定义变量
  10. IIS7 网站发布常见报错问题解决方案汇总