SGU 106 The equation 翻译 题解
2011-06-06 21:58
477 查看
106. 等式
时间限制:0.5s
内存限制:4096KB
对于等式ax+by+c=0,给出a,b,c,x1,x2,y1,y2,你必须要确定有多少个满足下面条件的整数对(x,y)存在,x1<=x<=x2,y1<=y<=y2。
输入:
包含整数a,b,c,x1,x2,y1,y2,所有数的绝对值都不大于108
输出:
输出结果个数。
================================华丽的分割线 ================================
首先,抱歉,四天前就翻译好了,现在才上交题解!实在没办法啊,好几个原因,第一,个人好奇心太强了!扩展欧几里德算法的原理一定要看懂,知道怎么证明才想动手,但是实在抱歉哈,还是有一些没看懂的地方……第二,SGU不给数据,错了不知道从哪里查起,确实麻烦!第三,SGU的怪编译器,在:
这样它就是不接受,第一个点就WA,但是按照网上一个人的代码,改成:
就AC了……无语吧,GCC我真没印象有I64d这玩意儿,就算有,是我才学疏浅,但是,但是……lld分明是C99中实用的,不信去《C Primer Plus》里去看!!
================================华丽的分割线 ================================
算法分析,这题用到了扩展欧几里德原理。
关于扩展的分析看上面的链接吧,接着简单分析一下,题意很清晰!直接贴思路:
当a==0,b==0时,c若等于0则答案就是题目的范围内的所有整数点。
若a==0时,by=-c,c是b的倍数,且在范围内就有答案,否则0个。
当b==0时,ax=-c,c是a的倍数,且在范围内就有答案,否则0个。
如果上面的条件都不符合,则使用扩展欧几里德算法。
时间限制:0.5s
内存限制:4096KB
对于等式ax+by+c=0,给出a,b,c,x1,x2,y1,y2,你必须要确定有多少个满足下面条件的整数对(x,y)存在,x1<=x<=x2,y1<=y<=y2。
输入:
包含整数a,b,c,x1,x2,y1,y2,所有数的绝对值都不大于108
输出:
输出结果个数。
================================华丽的分割线 ================================
首先,抱歉,四天前就翻译好了,现在才上交题解!实在没办法啊,好几个原因,第一,个人好奇心太强了!扩展欧几里德算法的原理一定要看懂,知道怎么证明才想动手,但是实在抱歉哈,还是有一些没看懂的地方……第二,SGU不给数据,错了不知道从哪里查起,确实麻烦!第三,SGU的怪编译器,在:
long long i; scanf("%lld", &i);
这样它就是不接受,第一个点就WA,但是按照网上一个人的代码,改成:
long long i; scanf("%I64d", &i);
就AC了……无语吧,GCC我真没印象有I64d这玩意儿,就算有,是我才学疏浅,但是,但是……lld分明是C99中实用的,不信去《C Primer Plus》里去看!!
================================华丽的分割线 ================================
算法分析,这题用到了扩展欧几里德原理。
关于扩展的分析看上面的链接吧,接着简单分析一下,题意很清晰!直接贴思路:
当a==0,b==0时,c若等于0则答案就是题目的范围内的所有整数点。
若a==0时,by=-c,c是b的倍数,且在范围内就有答案,否则0个。
当b==0时,ax=-c,c是a的倍数,且在范围内就有答案,否则0个。
如果上面的条件都不符合,则使用扩展欧几里德算法。
#include <stdio.h> #include <stddef.h> #include <stdlib.h> long long a, b, c; long long extgcd(long long a, long long b, long long *x, long long *y) { int t, s; if(b == 0){ *x = 1; *y = 10; return a; } t = extgcd(b, a % b, x, y); s = *x; *x = *y; *y = s - a / b * (*y); return t; } #define max(a, b) ((a)>(b)?(a):(b)) #define min(a, b) ((a)<(b)?(a):(b)) #define swap(a, b) (a)^=(b);(b)^=(a);(a)^=(b); int main(int argc, char **argv) { long long x1, x2; long long y1, y2; long long x, y, t; long long ans = 0; // scanf ("%I64d%I64d%I64d", &a, &b, &c); c = -c; scanf ("%I64d%I64d%I64d%I64d", &x1, &x2, &y1, &y2); // scanf("%d%d%d", &a, &b, &c); // scanf("%d%d", &x1, &x2); // scanf("%I64d%d", &y1, &y2); // c = -c; if(a == 0 && b == 0){ if(c == 0){ ans = (x2 - x1 + 1) * (y2 - y1 + 1); } }else if(a == 0){ if(c % b == 0 && c / b >= y1 && c / b <= y2){ ans = x2 - x1 + 1; } }else if(b == 0){ if(c % a == 0 && c / a >= x1 && c / a <= x2){ ans = y2 - y1 + 1; } }else{ t = extgcd(a, b, &x, &y); if(c % t == 0){ x *= c / t; y *= c / t; // printf("%d %d\n", x, y); long long lx, ly; long long rx, ry; lx = (x1 <= x || (x1 - x) * t % b == 0) ? ((x1 - x) * t / b) : ((x1 - x) * t / b + 1); rx = (x2 >= x || (x2 - x) * t % b == 0) ? ((x2 - x) * t / b) : ((x2 - x) * t / b - 1); ly = (y1 <= y || (y - y1) * t % a == 0) ? ((y - y1) * t / a) : ((y - y1) * t / a - 1); ry = (y2 >= y || (y - y2) * t % a == 0) ? ((y - y2) * t / a) : ((y - y2) * t / a + 1); if(lx > rx){ swap(lx, rx); } if(ly > ry){ swap(ly, ry); } // printf("%d %d %d %d\n", lx, rx, ly, ry); if(ry >= lx && rx >= ly){ ans = min(rx, ry) - max(lx, ly) + 1; } } } printf("%I64d\n", ans); return 0; }
相关文章推荐
- SGU106 The equation(数论)
- SGU 106. The equation 扩展欧几里德
- SGU106 The equation[扩展欧几里德算法]
- 数论 + 扩展欧几里得 - SGU 106. The equation
- SGU 106 The equation
- H - The equation——(SGU 106)
- [SGU]106. The Equation
- SGU 106 The equation
- SGU 106 The equation
- 数论 + 扩展欧几里得 - SGU 106. The equation
- SGU 106 The equation(扩展欧几里德)
- sgu 106 The equation
- SGU106 - The equation
- SGU 106 The equation
- SGU 106 The equation ----扩展欧几里得
- sgu 106 The equation
- sgu106 The Equation 扩展欧几里德
- sgu-106-The equation
- SGU 106 The equation (扩展GCD/多特判)
- SGU 106. The equation 解题报告(模线性方程)