luogu2666 Bessie的秘密牧场

来源:互联网 发布:ubuntu 14.04 卸载kde 编辑:程序博客网 时间:2024/05/10 16:55

题目背景

背景就是描述,描述就是背景。

题目描述

Farmmer John最近收割了几乎无限多块牧草,将它们堆放在空地上。这些牧草都是正方形的,而且都有非负整数长度的边长(当然有0)。一天它的奶牛Bessie发现了这些美味的牧草,于是希望把它们种在自己的秘密牧场上。他总将草皮分割成1*1的小块,以放入他牧场上的N个格子中。

Bessie感兴趣的是,她若选取四块会有多少种不同方法。如果N=4,那么她就有5种不同分发:(1,1,1,1),(2,0,0,0),(0,2,0,0),(0,0,2,0),(0,0,0,2),括号内数表示边长。注意这里不讲究顺序,如(1,2,3,4)与(4,3,2,1)是两种不同方法。

输入输出格式

输入格式:

仅一行,一个整数N。

输出格式:

同样为一行,包含一个整数,为方案总数。

输入输出样例

输入样例#1:
4
输出样例#1:
5



说明

对于100%的数据,1<=N<=10000。

—————————————————————————————————————————————————————————————

好吧,一开始没看懂题目什么意思
这里做一下解释:
四个位置 每个位置的数平方和=n
求有多少种方案

鉴于完全平方数的特殊性,以及只有四个位置
可以通过枚举,直接统计出答案
另一个,就是搜索
不过搜索好像麻烦了点
一个剪枝:第四个位置可以由前三个位置推出来

值得注意的是 sqrt 的返回值是double

穷举
一开始没有赋f[0]=1;
结果就wa了
一定要好好初始化啊
#include<bits/stdc++.h>#define MAXN 10001using namespace std;template <typename T> void read(T &x){x=0;int f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;for(;isdigit(ch);ch=getchar())x=(x<<1)+(x<<3)+ch-'0';x*=f;}bool f[MAXN];int ans;int main(){for(int i=0;i<=100;++i) f[i*i]=1;int n;read(n);int curr=(int)sqrt(n);//cout<<curr<<endl;for(int i=0;i<=curr;++i){for(int j=0;j<=curr;++j){if(i*i+j*j>n) continue;for(int k=0;k<=curr;++k){if(i*i+j*j+k*k>n) continue;//cout<<i<<" "<<j<<" "<<k<<endl;if(f[n-i*i-j*j-k*k]) /*cout<<i<<" "<<j<<" "<<k<<endl,*/++ans;}}}printf("%d\n",ans); return 0;}

搜索
第一次return的位置放错了
无限递归下去导致爆栈
第二次补上了判重+剪枝
结果tot+=a[k]*a[k]少写了一个a[k]

some points:
考场记得写对拍吧
小数据即可
提高写代码的速度
编程的时候一定要小心细节

上次看知乎意外看见了一个好玩的调试方法
找到手边的一个物件儿(小黄鸭
跟他一点一点讲你的程序
相当于模拟一遍
哪里讲不下去了
就是哪里出了问题
emmmmmm

#include<bits/stdc++.h>#define MAXN 10001using namespace std;template <typename T> void read(T &x){x=0;int f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;for(;isdigit(ch);ch=getchar())x=(x<<1)+(x<<3)+ch-'0';x*=f;}bool f[MAXN];int n;int curr,ans;int tot;int a[5];bool vis[101][101][101];void debug(){for(int i=1;i<=4;++i) cout<<a[i]<<" ";cout<<endl;}void dfs(int now){/*cout<<now<<":"<<endl;debug();*/if(now==4){if(!vis[a[1]][a[2]][a[3]]&&f[n-a[1]*a[1]-a[2]*a[2]-a[3]*a[3]]){++ans;//cout<<a[1]<<" "<<a[2]<<" "<<a[3]<<endl;vis[a[1]][a[2]][a[3]]=1;}return;}for(int i=0;i<=curr;++i){a[now]=i;tot=0;for(int k=1;k<=now;++k) tot+=a[k]*a[k];//cout<<"tot="<<tot<<endl;if(tot>n) continue;dfs(now+1);}}int main(){for(int i=0;i<=100;++i) f[i*i]=1;read(n);curr=(int)sqrt(n);dfs(1);printf("%d\n",ans); return 0;}













原创粉丝点击