250分的题目实在是250 主要就是看读题速度了
500分的题目 这个有点小搞 但是看起来也不是很难的 这样是没有想到方法 也是平时做的少了
题目大意:
就是在一个范围的数中算出某些数的个数 这些数满足不能被平方数整除。
第一感的想法就是 对于这里的每个数都应该判断下是否可以满足条件然后统计所有满足条件的数的数目。
首先要判断一个数是否能被平方数正常 那么就需要用比他小的每个平方数去尝试。由于min在1000,000,000,000 max在min,min+1000,100这样做肯定是不可以的。
但是换个思路 我们是否可以求出在范围之中所有可以被平方数整除的数的个数了? 这样做的好处就是在于 虽然min和max会很大 但是max-min确只有1000,000。
于是我们可以这样做 首先求出可能被max整除的所有平方数 即
for(long i=2;i<=1000000;i++)
{
if (i * i <= max)
numm.Add(i * i);
else
break;
}
一个数可以被平方数整除 那么他肯定是平方数的倍数 所以把上面算出来的平方数的倍数都算出来 而且判断倍数是否落在范围之内 这里有2个技巧就是求倍数的时候要从大于或等于min的数开始算 第二个要记录倍数是否已经出现过
Hashtable table = new Hashtable();
for (int i = 0; i < numm.Count;i++ )
{
for(long j=(long)min/numm[i];j<=(long)max/numm[i]+1;j++)
{
long tt = numm[i] * j;
if(min<=tt&&tt<=max)
{
if(table.ContainsKey(tt)==false)
{
table.Add(tt, 1);
res++;
}
}
}
}
最后 max-min+1-res 就是要求的结果了。
但是在比赛的时候 考虑多了没有直接用的平方数去计算倍数 而是用了素数的平方去计算倍数 结果在测试的时候 某些样例会出现+1的错误结果 有点考虑过了。直接用所有的平方数就是可以了因为范围不是很大 复杂度可以被接受
至于第三题 看别人的解答 应该是一道 最大流的题目 还要考虑下。
整体来说 比赛做的很一般 很久没有做了 水平下降了