各种刁钻的题目 (坑坑坑。。。。)

https://vjudge.net/contest/232973#problem/G

下面介绍一种runtime error(运行时出错)

#include<iostream>
#include<stdio.h>
using namespace std;
long long gcd(long long n,long long m)
{
    return m>0?gcd(m,n%m):n;
}
int lcm(int n,int m,int r)
{
    return n*m/r;
}
int main()
{
	int t;
	long long a[2100];
	scanf("%d",&t);
	while(t--)
	{
		long long n,sum=0,ans=0,sum1=0;
		scanf("%I64d",&n);
		for(int i=0;i<n;i++)
		{
			scanf("%I64d",&a[i]);
			sum+=a[i];
		}
		for(int i=0;i<n;i++)
		{
		    long long s=1;
		    sum1=0;
			for(int j=i;j<n;j++)
			{
			    sum1+=a[j];
			    s=lcm(s,a[j],gcd(s,a[j]));//出错的地方在这里,s*a[j]可能会爆long long
			    if(s>sum)
                break;
                if(sum1%s==0)
                {
                   ans++;
                }
			}
		}
		printf("%I64d\n",ans);
	}
	return 0;
}

  

下面是一种ac代码,注意不仅主函数要用long long ,定义函数的时候也要用long long ,否则又是wa... !!!!!!!注意控制爆范围

#include<iostream>
#include<stdio.h>
const long long inf=2e12;
using namespace std;
long long gcd(long long  n,long long m)
{
    return m>0?gcd(m,n%m):n;
}
int lcm(int n,int m,int r)
{
    return n*m/r;
}
int main()
{
	int t;
	long long a[2100];
	scanf("%d",&t);
	while(t--)
	{
		long long n,sum=0,ans=0,sum1=0;
		scanf("%I64d",&n);
		for(int i=0;i<n;i++)
		{
			scanf("%I64d",&a[i]);
			sum+=a[i];
		}
		for(int i=0;i<n;i++)
		{
		    long long s=1;
		    sum1=0;
		    for(int j=i;j<n;j++)
		    {
			sum1+=a[j];
		        //s=lcm(s,a[j],gcd(s,a[j]));
	        	s=s/gcd(s,a[j]);//就是这个地方加了一个控制爆范围!!!
			if(a[j]>inf/s)
                        break;
                        s=s*a[j];
                        if(sum1%s==0)
                        {
                        ans++;
                        }
		    }
		}
		printf("%I64d\n",ans);
	}
	return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/caijiaming/p/9147479.html