题意:一个等差数列是一个能表示成(a, a+b, a+2b,..., a+nb (n=0,1,2,3,...))的数列.在这个问题中a是一个非负的整数,b是正整数。写一个程序来找出在双平方数集合(双平方数集合是所有能表示成p的平方 + q的平方的数的集合,其中p和q为非负整数)S中长度为n的等差数列.
分析:先求出集合S,然后对于一个等差数列,我们只要枚举出前面两个数,就可以得到公差d,即可以推出整个数列,然后对于推出来的每一项,我们判断是否在集合S之中即可.然后有一个小优化,就是当我们枚举完前两项后,我们直接先判断最大项如果比集合S中的最大值大,说明此次枚举不合法.
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#define ll long long
using namespace std;
inline int read(){
int x=0,o=1;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')o=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*o;
}
const int N=200005;
int S[N],tong[N];
struct ppx{int a,b;}ans[N];
inline bool cmp(const ppx &x,const ppx &y){return x.b==y.b?x.a<y.a:x.b<y.b;}
int main(){
int n=read(),m=read(),tot=0,Ans=0;
for(int i=0;i<=m;++i)
for(int j=0;j<=i;++j){
if(!tong[i*i+j*j])S[++tot]=i*i+j*j;
tong[S[tot]]=1;
}
sort(S+1,S+tot+1);
for(int i=1;i<=tot-n+1;++i)
for(int j=i+1;j<=tot-n+2;++j){
int d=S[j]-S[i],p=S[j],T=n-2,bj=1;
if(p+T*d>S[tot])break;
while(T--){
p+=d;
if(!tong[p]){bj=0;break;}
}
if(bj)ans[++Ans].a=S[i],ans[Ans].b=d;
}
if(!Ans){puts("NONE");return 0;}
sort(ans+1,ans+Ans+1,cmp);
for(int i=1;i<=Ans;++i)
printf("%d %d
",ans[i].a,ans[i].b);
return 0;
}
题意:农民约翰有三个容量分别是A,B,C升的桶,A,B,C分别是三个从1到20的整数, 最初,A和B桶都是空的,而C桶是装满牛奶的。有时,农民把牛奶从一个桶倒到另一个桶中,直到被灌桶装满或原桶空了。当然每一次灌注都是完全的。由于节约,牛奶不会有丢失。写一个程序去帮助农民找出当A桶是空的时候,C桶中牛奶所剩量的所有可能性。
分析:对于每一个状态,我们只有六种操作,即a给b,a给c,b给a,b给c,c给a,c给b,我们直接DFS穷举所有状态.然后类似于记忆化搜索,我们开一个visit[a][b][c]记录当前状态是否访问过,提高搜索效率.
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#define ll long long
using namespace std;
inline int read(){
int x=0,o=1;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')o=-1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*o;
}
int A,B,C,bj[25],visit[25][25][25];
inline void dfs(int a,int b,int c){
if(visit[a][b][c])return;
if(a==0)bj[c]=1;
visit[a][b][c]=1;
if(c){
if(a<A){
int now=min(A,a+c);
dfs(now,b,c-now+a);
}
if(b<B){
int now=min(B,b+c);
dfs(a,now,c-now+b);
}
}
if(b){
if(a<A){
int now=min(A,a+b);
dfs(now,b-now+a,c);
}
if(c<C){
int now=min(C,b+c);
dfs(a,b-now+c,now);
}
}
if(a){
if(b<B){
int now=min(B,a+b);
dfs(a-now+b,now,c);
}
if(c<C){
int now=min(C,a+c);
dfs(a-now+c,b,now);
}
}
}
int main(){
A=read(),B=read(),C=read();
dfs(0,0,C);
for(int i=0;i<=20;++i)if(bj[i])printf("%d ",i);//记得从0开始
printf("
");
return 0;
}