您的位置:首页 > 其它

SGU 106 The equation 扩展欧几里得好题

2013-07-27 11:54 483 查看
扩展欧几里得的应用……见算法竞赛入门经典p.179

注意两点:1.解不等式的时候除负数变号

2.各种特殊情况的判断( a=0 && b=0 && c=0 ) ( a=0 && b=0 && c!=0 ) ( a=0 && b!=0 )( a!=0 && b=0 )

能加深对扩展欧几里得的理解,不错的一题

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>

#define LL long long int

using namespace std;

void ExGcd( LL a, LL b, LL &d, LL &x, LL &y )
{
if ( !b )
d = a, x = 1, y = 0;
else
{
ExGcd( b, a % b, d, y, x );
y -= x * ( a / b );
}
return;
}

int main()
{
LL a, b, c, x1, x2, y1, y2;
while ( scanf( "%I64d%I64d%I64d%I64d%I64d%I64d%I64d", &a, &b, &c, &x1, &x2, &y1, &y2 ) == 7 )
{
if ( a == 0 && b == 0 )
{
if ( c == 0 )
printf( "%I64d\n", (x2 - x1 + 1)*(y2 - y1 + 1) );
else puts("0");
continue;
}
if ( a == 0 )
{
if ( (-c) % b == 0 )
{
LL y = (-c) / b;
if ( y >= y1 && y <= y2 ) puts("1");
else puts("0");
}
else puts("0");

continue;
}
if ( b == 0 )
{
if ( (-c) % a == 0 )
{
LL x = (-c) / a;
if ( x >= x1 && x <= x2 ) puts("1");
else puts("0");
}
else puts("0");
continue;
}
LL g, x0, y0;
ExGcd( a, b, g, x0, y0 );
if ( (-c) % g == 0 ) //如果有解
{
x0 = x0 * (-c) / g;
y0 = y0 * (-c) / g;

LL aa = a / g;
LL bb = b / g;
LL low, high;
if ( aa > 0 && bb > 0 )
{
low  = max( (x0 - x1) / bb, (y0 - y2) / aa );
high = min( (x2 - x0) / bb, (y0 - y1) / aa );
printf("%I64d\n", high - low + 1 );
}
else if ( aa > 0 && bb < 0 )
{
low  = max( (x2 - x0) / bb, (y0 - y2) / aa );
high = min( (x0 - x1) / bb, (y0 - y1) / aa );
printf("%I64d\n", high - low + 1 );
}
else if ( aa < 0 && bb > 0 )
{
low  = max( (x0 - x1) / bb, (y0 - y1) / aa );
high = min( (x2 - x0) / bb, (y0 - y2) / aa );
printf("%I64d\n", high - low + 1 );
}
else if ( aa < 0 && bb < 0 )
{
low  = max( (x2 - x0) / bb, (y0 - y1) / aa );
high = min( (x0 - x1) / bb, (y0 - y2) / aa );
printf("%I64d\n", high - low + 1 );
}
}
else puts("0");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: