POJ2115 C Looooops(扩展欧几里得)
来源:互联网 发布:网络暴走好声音 编辑:程序博客网 时间:2024/05/17 22:56
C Looooops
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 19837 Accepted: 5301
Description
A Compiler Mystery: We are given a C-language style for loop of type
I.e., a loop which starts by setting variable to value A and while variable is not equal to B, repeats statement followed by increasing the variable by C. We want to know how many times does the statement get executed for particular values of A, B and C, assuming that all arithmetics is calculated in a k-bit unsigned integer type (with values 0 <= x < 2k) modulo 2k.
for (variable = A; variable != B; variable += C) statement;
I.e., a loop which starts by setting variable to value A and while variable is not equal to B, repeats statement followed by increasing the variable by C. We want to know how many times does the statement get executed for particular values of A, B and C, assuming that all arithmetics is calculated in a k-bit unsigned integer type (with values 0 <= x < 2k) modulo 2k.
Input
The input consists of several instances. Each instance is described by a single line with four integers A, B, C, k separated by a single space. The integer k (1 <= k <= 32) is the number of bits of the control variable of the loop and A, B, C (0 <= A, B, C < 2k) are the parameters of the loop.
The input is finished by a line containing four zeros.
The input is finished by a line containing four zeros.
Output
The output consists of several lines corresponding to the instances on the input. The i-th line contains either the number of executions of the statement in the i-th instance (a single integer number) or the word FOREVER if the loop does not terminate.
Sample Input
3 3 2 163 7 2 167 3 2 163 4 2 160 0 0 0
Sample Output
0232766FOREVER
题目大意:
给定一个循环,循环的终止条件是刚好等于B的时候,其他条件会一直执行+C操作,初始值为A,现在知道机器为无符号k位,也就是数据范围为(0<=x<2^k),求是否会循环是否会终止,不能终止就输出FOREVER,其他情况输出循环了几次.
解题思路:
扩展欧几里得题目,首先我们要推出方程,kc + m * 2 ^ k = (B -A),c和k,(B-A)已知,所以c,k为系数,求一下c,k的最大公约数,根据欧几里得的定律,(B - A) mod gcd(c,k) == 0才有解,否则我们直接输出FOREVER,如果有解我们调用扩展欧几里得这个接口,可以得到一组解,要得到最后的解只要k * (B - A) / gcd(c,k)即可。扩展欧几里得详细的定理可见百度百科等其他博客。
AC代码:
#include<iostream>#include<cstdio>typedef long long int64;using namespace std;int64 gcd(int64 a,int64 b){ if(b == 0) return a; return gcd(b,a%b);}void extend_gcd(int64 a,int64 b,int64 &x,int64 &y) //扩展欧几里得{ if(b == 1) { x = 1; y = 1 - a; } else { int64 x1,y1; extend_gcd(b,a % b,x1,y1); x = y1; y = x1 - x * (a / b); }}int main(){ int64 a,b,c,k; //freopen("111","r",stdin); while(cin>>a>>b>>c>>k && a + b + c + k) { int64 temp1,temp2; int64 res; int64 d = 1LL << k; //cout<<d<<endl; int64 g = gcd(c,d); //gcd //cout<<g<<endl; int64 left = b - a; if(left % g != 0) { cout<<"FOREVER"<<endl; //无解 } else { c = c / g; d = d / g; extend_gcd(c,d,temp1,temp2); //kc + m * 2 ^ k = (b - a); /*if(temp1 < 0) temp1 += d; //一个周期,这样写WA,因为可能负很多*/ res = ((temp1 * (b - a) / g % d) + d) % d; //先模掉缩小范围,要求的数乘以右边的数再除以gcd就是答案 cout<<res<<endl; } } return 0;}
0 0
- POJ2115 C Looooops(扩展欧几里得)
- poj2115 C Looooops(扩展欧几里得)
- C Looooops poj2115 (扩展欧几里得+模线性方程)
- POJ2115 C Looooops(扩展欧几里得算法)
- POJ2115:C Looooops(扩展欧几里得)
- POJ2115 C Looooops(扩展欧几里得)
- poj2115--C Looooops(扩展gcd)
- POJ2115 C Looooops 推广的欧几里得算法
- C Looooops(扩展欧几里得)
- C Looooops(扩展欧几里得)
- poj2115 Looooops 扩展欧几里德
- 欧几里德 poj2115 C Looooops
- POJ2115 C Looooops
- POJ2115-C Looooops
- [POJ2115] C Looooops
- #POJ2115# C Looooops
- POJ2115-C Looooops
- POJ2115 C Looooops
- 科技论文中公式和序号怎么对齐
- 代码注释总结
- oracle中INSTR函数的用法
- 省市区字典数组
- NSRunloop的解析及autorelease的释放时机
- POJ2115 C Looooops(扩展欧几里得)
- OpenCV中图像及子图像ROI之间的复制
- Android 折线图的实现
- caffe python批量抽取图像特征
- 我需要下载哪个版本的eclipse?
- 指针的概念
- ubuntu下opencv的配置
- 阿里巴巴校招内推简历筛选方案(总结篇)
- iOS开发雕虫小技之傻瓜式定位神器-超简单方式解决iOS后台定时定位