您的位置:首页 > 其它

ZOJ 3768 Continuous Login(迭代搜索||夹逼)

2015-05-11 21:17 309 查看
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5231

 

题意:

求一个数n 最少,可以由几个这样 1...x的数的和组成

 

分析:

多写几组可以发现规律 最多由三组组成,然后枚举一个值,然后用夹逼求另外两个的值。

代码如下:

#include <iostream>
#include <cstdio>
#include <map>
#include <vector>
#include <cstring>
#include <algorithm>

#define PB push_back
#define MP make_pair
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define DWN(i,h,l) for(int i=(h);i>=(l);--i)
#define IFOR(i,h,l,v) for(int i=(h);i<=(l);i+=(v))
#define CLR(vis) memset(vis,0,sizeof(vis))
#define MST(vis,pos) memset(vis,pos,sizeof(vis))
#define MAX3(a,b,c) max(a,max(b,c))
#define MAX4(a,b,c,d) max(max(a,b),max(c,d))
#define MIN3(a,b,c) min(a,min(b,c))
#define MIN4(a,b,c,d) min(min(a,b),min(c,d))
#define PI acos(-1.0)
#define INF 1000000000
#define LINF 1000000000000000000LL
#define eps 1e-8
#define LL long long
#define maxn 120010
using namespace std;

int a[maxn];
map<int ,int >mp;
vector<int >ans;
int cnt;
void init(){
CLR(a);
mp.clear();
LL sum=0;
cnt=0;
FOR(i,1,maxn-1){
a[i]=a[i-1]+i;
mp[a[i]]=i;
cnt++;
if(a[i]>123456789) return;
}
}

int main()
{
init();
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
int pos=lower_bound(a+1,a+cnt+1,n)-a;
if(a[pos]==n){
printf("%d\n",pos);
continue;
}
vector<int >ans;
REP(i,pos+1){
ans.clear();
if(i) ans.push_back(i);
bool tag = 0;
int l = 1,r=pos;
while(l<=r){
if(a[l]+a[r]<n-a[i]) l++;
else if(a[l]+a[r]>n-a[i]) r--;
else{
ans.push_back(l);
ans.push_back(r);
tag = 1;
break;
}
}
if(tag){
printf("%d",ans[0]);
FOR(j,1,ans.size()-1) printf(" %d",ans[j]);
puts("");
break;
}
}
}
return 0;
}

方法二:

迭代DFS,我们枚举深度,然后做DFS就可以得到最少的了。

代码如下:

#include <iostream>
#include <cstdio>
#include <map>
#include <vector>
#include <cstring>
#include <algorithm>

#define PB push_back
#define MP make_pair
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define DWN(i,h,l) for(int i=(h);i>=(l);--i)
#define IFOR(i,h,l,v) for(int i=(h);i<=(l);i+=(v))
#define CLR(vis) memset(vis,0,sizeof(vis))
#define MST(vis,pos) memset(vis,pos,sizeof(vis))
#define MAX3(a,b,c) max(a,max(b,c))
#define MAX4(a,b,c,d) max(max(a,b),max(c,d))
#define MIN3(a,b,c) min(a,min(b,c))
#define MIN4(a,b,c,d) min(min(a,b),min(c,d))
#define PI acos(-1.0)
#define INF 1000000000
#define LINF 1000000000000000000LL
#define eps 1e-8
#define LL long long
#define maxn 120010
using namespace std;

int a[maxn];
map<int ,int >mp;
vector<int >ans;
int cnt;
void init(){
CLR(a);
mp.clear();
LL sum=0;
cnt=0;
FOR(i,1,maxn-1){
a[i]=a[i-1]+i;
mp[a[i]]=i;
cnt++;
if(a[i]>123456789) return;
}
}

bool flag;

void dfs(int dep,int val){
if(dep==1){
if(mp[val]){
ans.push_back(mp[val]);
flag = true;
}
return;
}
int pos = upper_bound(a+1,a+cnt+1,val)-a;
DWN(i,pos-1,1){
ans.push_back(mp[a[i]]);
dfs(dep-1,val-a[i]);
if(flag) return;
ans.erase(--ans.end());
}
}

int main()
{
init();
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
flag=false;
ans.clear();
FOR(i,1,cnt){
dfs(i,n);
if(flag){
printf("%d",ans[0]);
FOR(i,1,ans.size()-1) printf(" %d",ans[i]);
puts("");
break;
}
}
}
return 0;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: