【USACO1.5】解題報告
阿新 • • 發佈:2018-11-09
前言
這章只有兩道題,但是質量都不比上一章低。
第一題正解肯定很難,但是資料神奇般的把
即
的程式過掉了。。。
第二題標準的深搜。
USACO:http://train.usaco.org
1.5.2.Arithmetic Progressions
這裡只能給出神奇的卡常解法。對於想找正解的
們感到非常抱歉。
首先需要證明當
時有
。這裡給出題解的證明,非常簡潔明瞭。
設
1.當 為偶數。設 ,則 。
2.當 一奇一偶。不妨令 ,則
3.當 為奇數。設 ,則
由於 中有1個偶數,故 為偶數,同理, 為偶數,即 為偶數,有 ( 為自然數)
即 .
即 , 為偶數.
若 ,則 為偶數。由於能寫成 的形式的數無法寫生兩個完全平方數的和( ),即能 寫成 的形式,但已證能寫成 形式的數一定不是完全平方數),故 為奇數,矛盾。
即 。
那麼就分成 和 的兩塊,前者每次加1,後者每次加4就可以了。
程式碼:
/*
ID:ssl_zyc2
TASK:ariprog
LANG:C++
*/
#include <cstdio>
#define N 135010
using namespace std;
int n,m,p[N],maxn,ok,OK;
int main()
{
freopen("ariprog.in","r",stdin);
freopen("ariprog.out","w",stdout);
scanf("%d%d",&n,&m);
if (n<4)
{
for (register int i=0;i<=m;i++)
for (register int j=0;j<=m;j++)
p[i*i+j*j]=1;
for (register int j=1;j<=m*m*2;j++)
for (register int i=0;i<=m*m*2;i++)
{
if (i+(n-1)*j>m*m*2) break;
ok=1;
for (register int k=0;k<n;k++)
if (!p[i+k*j])
{
ok=0;
break;
}
if (ok)
{
printf("%d %d\n",i,j);
OK=1;
}
}
}
else
{
for (register int i=0;i<=m;i++)
for (register int j=0;j<=m;j++)
p[i*i+j*j]=1;
for (register int j=4;j<=m*m*2;j+=4)
for (register int i=1;i<=m*m*2;i++)
{
if (i+(n-1)*j>m*m*2) break;
ok=1;
for (register int k=0;k<n;k++)
if (!p[i+k*j])
{
ok=0;
break;
}
if (ok)
{
printf("%d %d\n",i,j);
OK=1;
}
}
}
if (!OK) printf("NONE\n");
return 0;
}
1.5.3.Mother’s Milk
思路:
標準的深搜。每次有六種轉移方法: