首页 > 代码库 > poj 1416 Shredding Company 模拟+枚举
poj 1416 Shredding Company 模拟+枚举
题意:
给一个目标数和一个待分割数,可以对待分割数进行任意划分,比如将带分割数12305分为12,30,5,问将分好的数加起来最接近且不超过目标数的分割方案。
分析:
关键是在对带分割数的任意划分,直接for循环枚举状态,比如状态10101(二进制)表示将12305分为1,23,05.
代码:
#include <iostream> #include <vector> using namespace std; int t,len; char a[12]; int vis[1000010]; int sta[1000010]; int tmp[12]; vector<int> ans[1024]; int get_num(int l,int r) { int i,sum=0; for(i=l;i<=r;++i) sum=10*sum+(a[i]-'0'); return sum; } void generate(int p) { ans[p].clear(); int s=p; for(int i=len-1;i>=0;--i,p/=2) tmp[i]=p%2; int l=0,sum=0; for(int i=0;i<len;++i) if(tmp[i]==1){ int num=get_num(l,i); l=i+1; sum+=num; ans[s].push_back(num); } ++vis[sum]; sta[sum]=s; } int main() { while(scanf("%d%s",&t,a)==2){ if(t==0&&a[0]=='0') break; memset(vis,0,sizeof(vis)); int i; len=strlen(a); for(i=0;i<(1<<len);++i) if(i%2==1) generate(i); int flag=0; for(i=t;i>=1;--i) if(vis[i]>1){ printf("rejected\n"); flag=1; break; }else if(vis[i]==1){ printf("%d ",i); int s=sta[i]; for(int j=0;j<ans[s].size();++j) printf("%d ",ans[s][j]); printf("\n"); flag=1; break; } if(flag==0) printf("error\n"); } return 0; }
poj 1416 Shredding Company 模拟+枚举
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。