hdu 4611

2013 hdu 다 교 리그 2 의 첫 번 째 문 제 는 당시 동료 들 이 두 상자 개수 의 최소 공배수 가 주기 라 고 말 했다.
만약 두 수의 최소 공배수 가 비교적 클 때 (최대 999900000), 두루 구하 면 틀림없이 시간 을 초과 할 것 이다
그 당시 에 여러 가지 규칙 을 찾 으 려 고 했 지만 찾 지 못 했 습 니 다. 마지막 으로 저 는 옮 겨 다 니 는 최적화 가 생각 났 습 니 다. 바로 매번 한 개의 숫자 만 늘 리 는 것 이 아니 라
가장 큰 미 공 을 구 하 는 것 은 두 상자 의 번호 가 점점 증가 하 는 것 이다. 그러면 매번 첫 번 째 차 이 를 더 한 미 동반 만 필요 하 다.
공의 번호 에 미 를 더 하면 매번 1 을 더 하 는 것 보다 빠 르 고 옮 겨 다 니 는 구간 을 줄 일 것 이다.
그 결과 가장 큰 9999000 원 의 답 을 구 하 는 순간 나 와 자신 감 이 커 졌 고 결 과 는 몇 번 이나 틀 렸 다.
변 수 를 64 자리 로 바 꿀 생각 이 있 었 는데 예전 에 문 제 를 풀 때 이런 문제 가 있 었 습 니 다.
64 비트 와 int 혼합 연산 에 오류 가 발생 하면 수정 후 abs 함수 에 경고 가 있 으 면 다시 바 꿉 니 다.
폭력 이 나 온 결과 와 는 다른 몇 가지 답 이 있 었 다.
오늘 64 명 을 고치 면 A 가 됩 니 다. 그 후회,,,,,,,,,,,,,,,,,,,,,,,,,,,
#include <stdio.h>
#include <string.h>
__int64 gcd(__int64 a,__int64 b)
{
    if(b==0)return a;
    else return gcd(b,a%b);
}
__int64 abs(__int64 a)
{
	if(a>0)return a;
	return -a;
}
__int64 cont(__int64 n,__int64 a,__int64 b)
{
    __int64 ans,i,mi;
    i=0;ans=0;
	while(i<n)
	{
		mi=(a-i%a)>(b-i%b)?(b-i%b):(a-i%a);
		if(i+mi>=n)
			mi=n-i;
		ans+=abs(i%a-i%b)*mi;
		i+=mi;
	}
	return ans;
}
int main()
{
    int T;
    __int64 n,a,b,t;
    __int64 ans;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%I64d%I64d%I64d",&n,&a,&b);
		t=gcd(a,b);
		t=a*b/t;
        if (t>=n)	ans=cont(n,a,b);		
        else ans=cont(t,a,b)*(n/t)+cont(n%t,a,b);
        printf("%I64d
",ans); } return 0; }

좋은 웹페이지 즐겨찾기