UVALive 3667 Ruler (模拟)

来源:互联网 发布:matlab计算矩阵编程 编辑:程序博客网 时间:2024/05/15 02:00

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1668


题意:

     给定一些长度,求在尺上最少标几个刻度,可以使得利用刻度差求得给定的所有长度。在满足刻度数量最少的前提下,还需保证总长度最小。

解题:

    好复杂的思路,写了一遍。

    n的50是个幌子,m最大为7。组合数最大为21。利用某某性质,可以用原有差值减出结果集合。数量为21*20/2。然后递增元素个数在结果集中选择元素,并计算是否能够囊括所有的给定元素,若可以,则为结果。(0和最大元素必选)

    额,讲的好不清楚。


代码:

#include <cstdio>#include <iostream>#include <string>#include <cstring>#include <set>using namespace std;int arr[50],pro[210],cho[210],p1,p2;bool vis[1000010],sign;void dfs(int p,int t,int pos){  if(sign)return;  int cnt=0;  cho[p]=pro[pos];  if(p==t)  {  set <int> c;  for(int i=0;i<p+1;i++)  for(int j=i+1;j<=p+1;j++)  c.insert(cho[j]-cho[i]);  for(int i=1;i<p1;i++)  vis[arr[i]]=1;  set <int> :: iterator it;  for(it=c.begin();it!=c.end();it++)  {         if(vis[*it]) {// cout<<vis[*it]<<endl; cnt++; vis[*it]=0; }  }  if(cnt==p1-1)    sign=1;  return;  }  for(int i=pos+1;i<p2-1;i++)  dfs(p+1,t,i);}int main(){int n,cnt=0,tmp;set <int> s,x;while(scanf("%d",&n)&&n){printf("Case %d:\n",++cnt);sign=0;memset(vis,0,sizeof(vis));p1=1;p2=0;s.clear();x.clear();for(int i=0;i<n;i++){scanf("%d",&tmp);s.insert(tmp);}    set <int> ::iterator it;if(s.size()==1){it=s.begin();printf("2\n%d %d\n",0,*it);continue;}else if(s.size()==2){it=s.begin();printf("3\n%d %d",0,*it);printf(" %d\n",*(++it));continue;}for(it=s.begin();it!=s.end();it++)arr[p1++]=*it;        arr[0]=0;for(int i=0;i<p1;i++)for(int j=i+1;j<p1;j++)x.insert(arr[j]-arr[i]);for(it=x.begin();it!=x.end();it++)pro[p2++]=*it;for(int i=1;i<=5;i++){   cho[0]=0;   cho[i+1]=pro[p2-1];   for(int j=1;j<p2-1;j++)   {   dfs(1,i,j);   if(sign)   {   printf("%d\n",i+2);   printf("%d",cho[0]);   for(int k=1;k<=i+1;k++)   printf(" %d",cho[k]);   printf("\n");   break;   }}   if(sign)break;}}return 0;}



0 0