POJ 1011 Sticks

 

写这篇文章呢,有个很邪恶的目的,就是提高博客的访问量——据我所知“POJ 1011”这个关键词似乎非常极其的热门——是不是?

当时我做这题的时候的确就写了下面这么长的代码,不过你读一遍就会发现 3/4 的内容都被注释掉了,那些内容多少能说明我的思想,而剩下来的那部分是可以 AC 的。


PS. 我真的不喜欢全局变量。


PPS. 以后这里不会再放ACM的代码了;感兴趣的话可以等河蟹在睡觉的某天访问 hi-if.blogspot.com 看看。

 

    • #if 1 // includes
    • #include <memory.h>
    • #include <iostream>
    • #include <algorithm>
    • #include <functional>
    • using namespace std;
    • #endif   //  for folding
    • #define POJ_IS_STUPID 0
    • #if     POJ_IS_STUPID
    • #if 0
    • struct state { //里面这些东西不一定都用得着倒是了
    •     int sticks[51];  // 长度为 i 的木棍有 sticks[i] 个。
    •     int figures[51]; // 各种长度
    •     int nfigures;
    •     int length;
    •     int target;
    •     int remained;
    •     int max;
    •     int min;
    •     int sum;
    • };
    • template <class T>
    • size_t inv_bin_search(T* array, size_t len, T const& n) {
    •     size_t a=0,b=len,m1,m2=-1;
    •     for (m1=(a+b)>>1;m1!=m2;) {
    •         m2=m1;
    •         if     (array[m1]==n) return m1;
    •         else if (array[m1]>n)  a=m1;
    •         else b=m1;
    •         m1=(a+b)>>1;
    •     }
    •     if (array[m1]<n) return m1;
    •     else return m1-1;
    • }
    • bool match(state& st, int target) {
    •     bool first=(target==st.target);
    •     int i,*j;
    •     if (target>st.max) {
    •         //for(i=st.max;i>=st.min;--i){
    •         for (j=st.figures;i=*j;++j) {
    •             if (st.sticks[i]) {
    •                 --st.sticks[i];
    •                 st.sum-=i;
    •                 if (match(st,target-i))
    •                     return true;
    •                 st.sum+=i;
    •                 ++st.sticks[i];
    •                 if (first)
    •                     return false;
    •             }
    •         }
    •         return false;
    •     } else if (target<st.min) {
    •         return false;
    •     } else if (target>st.sum) {
    •         return false;
    •     } else if (target==st.sum) {
    •         return true;
    •     }
    •     if (st.sticks[target]) {
    •         --st.sticks[target];
    •         st.sum-=target;
    •         if (--st.remained==0) return true;
    •         if (match(st,st.target))
    •             return true;
    •         ++st.remained;
    •         st.sum+=target;
    •         ++st.sticks[target];
    •         return false;
    •     }
    •     for (j=st.figures+inv_bin_search<int>(st.figures,st.nfigures,target);
    •         *j>=target&&*j;++j);
    •     for (;i=*j;++j) {
    •         if (st.sticks[i]) {
    •             --st.sticks[i];
    •             st.sum-=i;
    •             if (match(st,target-i))
    •                 return true;
    •             st.sum+=i;
    •             ++st.sticks[i];
    •             if (first)
    •                 return false;
    •         }
    •     }
    •     return false;
    • }
    • int main() {
    •     for (state s={{0},{0},0,0};cin>>s.length&&s.length;) {
    •         s.sum=0;
    •         s.max=0;
    •         s.min=100;
    •         int x,i,j,n=0;
    •         bool succeed=false;
    •         for (i=0;i<=50;++i)
    •             s.sticks[i]=0;
    •         for (i=0;i<s.length;++i) {
    •             cin>>x;
    •             if (!s.sticks[x]) {
    •                 s.figures[n]=x;
    •                 ++n;
    •             }
    •             ++s.sticks[x];
    •             s.sum+=x;
    •             if (x>s.max) s.max=x;
    •             if (x<s.min) s.min=x;
    •         }
    •         s.figures[n]=0;
    •         s.nfigures=n;
    •         sort(s.figures,s.figures+n,greater<int>());
    •         for (j=s.max;j<=s.sum/2;++j) {
    •             if (s.sum%j==0) {
    •                 s.target=j;
    •                 s.remained=s.sum/j;
    •                 if ( match(s,j) ) {
    •                     cout<<j<<endl;
    •                     succeed=true;
    •                     break;
    •                 }
    •             }
    •         }
    •         if (!succeed)
    •             cout<<s.sum<<endl;
    •     }
    •     return 0;
    • }
    • #else
    • struct state { //里面这些东西不一定都用得着倒是了
    •     int sticks[51];  // 长度为 i 的木棍有 sticks[i] 个。
    •     int figures[51]; // 各种长度
    •     int nfigures;
    •     int length;
    •     int target;
    •     int remained;
    •     int max;
    •     int min;
    •     int sum;
    • };
    • template <class T>
    • size_t inv_bin_search(T* array, size_t len, T const& n) {
    •     size_t a=0,b=len,m1,m2=-1;
    •     for (m1=(a+b)>>1;m1!=m2;) {
    •         m2=m1;
    •         if     (array[m1]==n) return m1;
    •         else if (array[m1]>n)  a=m1;
    •         else b=m1;
    •         m1=(a+b)>>1;
    •     }
    •     if (array[m1]<n) return m1;
    •     else return m1-1;
    • }
    • bool match(state& st, int target) {
    •     int (&sticks)[51]=st.sticks;
    •     int (&figures)[51]=st.figures;
    •     int &sum=st.sum;
    •     int &remained=st.remained;
    •     bool first=(target==st.target);
    •     int i,*j;
    •     if (target>st.max) {
    •         //for(i=st.max;i>=st.min;--i){
    •         for (j=figures;i=*j;++j) {
    •             if (sticks[i]) {
    •                 --sticks[i];
    •                 sum-=i;
    •                 if (match(st,target-i))
    •                     return true;
    •                 sum+=i;
    •                 ++sticks[i];
    •                 if (first)
    •                     return false;
    •             }
    •         }
    •         return false;
    •     } else if (target<st.min) {
    •         return false;
    •     } else if (target>st.sum) {
    •         return false;
    •     } else if (target==st.sum) {
    •         return true;
    •     }
    •     if (sticks[target]) {
    •         --sticks[target];
    •         sum-=target;
    •         if (--remained==0) return true;
    •         if (match(st,st.target))
    •             return true;
    •         ++remained;
    •         sum+=target;
    •         ++sticks[target];
    •         return false;
    •     }
    •     for (j=figures+inv_bin_search<int>(figures,st.nfigures,target);
    •         *j>=target&&*j;++j);
    •     for (;i=*j;++j) {
    •         if (sticks[i]) {
    •             --sticks[i];
    •             sum-=i;
    •             if (match(st,target-i))
    •                 return true;
    •             sum+=i;
    •             ++sticks[i];
    •             if (first)
    •                 return false;
    •         }
    •     }
    •     return false;
    • }
    • int main() {
    •     for (state s={{0},{0},0,0};cin>>s.length&&s.length;) {
    •         s.sum=0;
    •         s.max=0;
    •         s.min=100;
    •         int x,i,j,n=0;
    •         bool succeed=false;
    •         for (i=0;i<=50;++i)
    •             s.sticks[i]=0;
    •         for (i=0;i<s.length;++i) {
    •             cin>>x;
    •             if (!s.sticks[x]) {
    •                 s.figures[n]=x;
    •                 ++n;
    •             }
    •             ++s.sticks[x];
    •             s.sum+=x;
    •             if (x>s.max) s.max=x;
    •             if (x<s.min) s.min=x;
    •         }
    •         s.figures[n]=0;
    •         s.nfigures=n;
    •         sort(s.figures,s.figures+n,greater<int>());
    •         for (j=s.max;j<=s.sum/2;++j) {
    •             if (s.sum%j==0) {
    •                 s.target=j;
    •                 s.remained=s.sum/j;
    •                 if ( match(s,j) ) {
    •                     cout<<j<<endl;
    •                     succeed=true;
    •                     break;
    •                 }
    •             }
    •         }
    •         if (!succeed)
    •             cout<<s.sum<<endl;
    •     }
    •     return 0;
    • }
    • #endif
    • #else
    • #if 0 //以前的
    • struct state { //不想用全局变量, 又不应该在递归的函数中使用太多参数, so...
    •     int  sticks[65];
    •     bool thereis[65];
    •     int  length;
    •     int  sum;
    •     int  max;
    •     int  target;
    • };
    • bool dfs(state& st, int target, int nremained, int begin=0) {
    •     if ( target==0 ) {
    •         if ( nremained==1 )
    •             return true;
    •         else
    •             return dfs(st,st.target,nremained-1,1);
    •     } else {
    •         if (begin>=st.length)
    •             return false;
    •         bool first=(target==st.target),last=false;
    •         for (int i=begin;i<st.length;++i) {
    •             if (!st.thereis[i])
    •                 continue;
    •             if (st.sticks[i]>target) {
    •                 // if(first){return false;}//impossible
    •                 continue;
    •             }
    •             st.thereis[i]=false;
    •             last=(st.sticks[i]==target);
    •             if (dfs(st,target-st.sticks[i],nremained,i+1)) {
    •                 return true;
    •             } else {
    •                 st.thereis[i]=true;
    •                 if ( first||last ) return false;
    •                 for (;st.sticks[i]==st.sticks[++i];);
    •                 --i;
    •             }
    •         }
    •     }
    •     return false;
    • }
    • int main() {
    •     for (state s;cin>>s.length&&s.length;) {
    •         s.max=s.sum=0;
    •         int x;
    •         bool succeed=false;
    •         for (int i=0;i<s.length;++i) {
    •             cin>>x;
    •             s.sticks[i]=x;
    •             s.sum+=x;
    •             if (x>s.max) s.max=x;
    •             s.thereis[i]=true;
    •         }
    •         sort(s.sticks,s.sticks+s.length,greater<int>());
    •         s.sticks[s.length]=0;
    •         s.thereis[s.length]=false;
    •         for (int j=s.max;j<=s.sum/2;++j) {
    •             if (s.sum%j==0) {
    •                 s.target=j;
    •                 if ( dfs(s,j,s.sum/j) ) {
    •                     cout<<j<<endl;
    •                     succeed=true;
    •                     break;
    •                 }
    •             }
    •         }
    •         if (!succeed)
    •             cout<<s.sum<<endl;
    •     }
    •     return 0;
    • }
    • #else
    • int  g_sticks[65];
    • bool g_used[65];
    • int  g_length;
    • int  g_sum;
    • int  g_max;
    • int  g_min;
    • int  g_target;
    • bool dfs(int target, int remained, int begin) {
    •     if( target<g_min||begin>=g_length )
    •         return false;
    •     if (target==g_target) { //第一根
    •         for (int i=begin;i<g_length;++i) {
    •             if (g_used[i])
    •                 continue;
    •             g_used[i]=true;
    •             if(g_sticks[i]==target){ // 最后一根
    •                 if(remained==1)
    •                     return true;
    •                 if(dfs(g_target , remained-1, 1))
    •                     return true;
    •                 g_used[i]=false;
    •                 return false;
    •             } else if (dfs(target-g_sticks[i],remained,i+1))
    •                 return true;
    •             g_used[i]=false;
    •             return false;
    •         }
    •     } else {
    •         for (int i=begin;i<g_length;++i) {
    •             if (g_used[i])
    •                 continue;
    •             if (g_sticks[i]>target)
    •                 continue;
    •             g_used[i]=true;
    •             if(g_sticks[i]==target){ // 最后一根
    •                 if(remained==1)
    •                     return true;
    •                 if(dfs(g_target , remained-1, 1))
    •                     return true;
    •                 g_used[i]=false;
    •                 return false;
    •             }
    •             if (dfs(target-g_sticks[i],remained,i+1))
    •                 return true;
    •             g_used[i]=false;
    •             for(;g_sticks[i]==g_sticks[i+1];++i);
    •         }
    •     }
    •     return false;
    • }
    • //#include <fstream>
    • int main() {
    •     //ifstream fin("test.txt");
    •     istream& xin=cin;//fin;
    •     for (;xin>>g_length&&g_length;) {
    •         int x;
    •         bool succeed=false;
    •         g_max=g_sum=0;
    •         g_min=1000;
    •         for (int i=0;i<g_length;++i) {
    •             xin>>x;
    •             g_sticks[i]=x;
    •             g_sum+=x;
    •             if (x>g_max) g_max=x;
    •             if (x<g_min) g_min=x;
    •             g_used[i]=false;
    •         }
    •         sort(g_sticks,g_sticks+g_length,greater<int>());
    •         g_sticks[g_length]=0;
    •         g_used[g_length]=true;
    •         for (int j=g_max;j<=g_sum/2;++j) {
    •             if (g_sum%j==0) {
    •                 g_target=j;
    •                 if ( dfs(j,g_sum/j,0) ) {
    •                     cout<<j<<endl;
    •                     succeed=true;
    •                     break;
    •                 }
    •             }
    •         }
    •         if (!succeed)
    •             cout<<g_sum<<endl;
    •     }
    •     return 0;
    • }
    • #endif
    • #endif

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值