SRM 545 DIV2

SRM 545

250pt

题意:给定一组数,求这组数中是否存在一个数等于所有其它的数按位与(&)的值。

分析:因为a&b<=min(a,b)ha&a=a,所以就是求这组数所有的数按位与之后的是否等于最小值。

 

View Code
class ANDEquation 
{ 
        public: 
        int restoreY(vector <int> A) 
        { 
                int i,m,k,n=A.size();
                m=*max_element(A.begin(),A.end());
                for(k=0,i=1;i<n;i++)
                    if(A[i]<A[k])
                        k=i;
                  for(i=0;i<n;i++)
                      if(i!=k)
                          m&=A[i];
                return m==A[k]?m:-1;        
        } 
        
 
}; 

 

550pt

题意:给定一个字符串SminRevn,求逆序数不小于minRev,字典序不小于S和由前n个小写字母组成的字符串T.

分析:因为字典序要大于S,所以考虑在补全S字符的基础上交换字母的位置来增加逆序数

如果s的字典序不小于minRev,那s就是答案。

否则贪心,对于长度为n的字母组成的字符串,逆序数最大为n*(n-1)/2;

因为要使T字典序最小,所以从要末尾开始修改,修改的位数越多,可增加的逆序数也越多。

PS.在类中自定义比较函数时要放到类外

View Code
int Cmp(char a,char b)
{
    return a>b;
}

class StrIIRec 
{ 
        public:
        string recovstr(int n, int minInv, string s) 
        { 
            int i,j,k,m,rev[22]={0};
            bool used[22]={false};
            m=(int)s.size();
            for(i=0;i<m;i++)
                   used[s[i]-'a']=true;
               for(i=0;i<n;i++)
                   if(!used[i])
                       s.push_back('a'+i);
            for(i=n-2;i>=0;i--)
            {
                for(j=i+1;j<n;j++)
                       if(s[i]>s[j])
                       rev[i]++;
                   rev[i]+=rev[i+1];
            }
            m=rev[0];
            if(m>=minInv)
                   return s;
            for(i=n-2;i>=0;i--)
                   if(m-rev[i]+(n-i)*(n-i-1)/2>=minInv)
                       break;
            k=minInv-m+rev[i]-(n-i-1)*(n-i-2)/2;
            sort(s.begin()+i,s.end(),Cmp);
            swap(s[i],s[n-1-k]);
            sort(s.begin()+i+1,s.end(),Cmp);
            return s;
        } 
        

 
}; 

 

1000pt

题意:给定一张长为L+1,高为H+1的网格图,求符合下列条件的集合有多少种

1,包含K个格点

2K个点必须在一条直线上;

3,有且仅有一个点的高度为0;

分析:枚举步差步差来代表某个集合,用最大公约数判断是否是最小步差,即集合是否枚举过

 PS:有O(L*H)算法,没看懂

View Code
#define MAX 1000000007

class SpacetskE 
{ 
        public:
        int gcd(int a,int b)
        {
            return b?gcd(b,a%b):a;
        }
        int countsets(int L, int H, int K) 
        { 
            int i,j,n,m,a,b,x2,x1,y2;
            int c[222][222]={0};
            for(i=0;i<222;i++)
                c[i][0]=c[i][i]=1;
            for(i=2;i<222;i++)
                for(j=1;j<=i;j++)
                    c[i][j]=(c[i-1][j-1]+c[i-1][j])%MAX;
            if(K==1)
                return (L+1)*(H+1);
            for(m=i=0;i<=L;i++)
                m=(m+c[H+1][K])%MAX;
            for(x1=0;x1<=L;x1++)
                for(x2=0;x2<=L;x2++)
                    if(x1!=x2)
                        for(y2=1;y2<=H;y2++)
                        {
                            a=abs(x2-x1);
                            b=y2;
                            if(gcd(a,b)>1)
                                continue;
                            if(x2>x1)
                                n=min((L-x1)/a,H/b);
                            else
                                n=min(x1/a,H/b);
                            n++;
                            if(K<=n)
                                m=(m+c[n][K])%MAX;
                        }
            return m;
        }   
}; 

 

posted @ 2012-06-15 12:30    阅读(202)  评论(0编辑  收藏  举报