Codeforces Round #231 (Div2) 迟到的解题报告

题目A:

       给一个火柴等式,可以从左边移动一根到右边,也可以从右边移到左边,但是不能移动“+”,”=“的火柴,

而且加法里面的数都要大于0(很重要的条件),基本上注意到这点的都过了,没注意的都被HACK了。

  #include<iostream>

#include<math.h>
#include<algorithm>

#include<string>
#include<set>
#include<map>
using namespace std;
int n;

int main()
{
   string s;
   cin>>s;
   int a,b;
   a=b=0;
   int i=0;
   for (;i<s.size();i++)
   {
    if (s[i]=='|') a++;
    if  (s[i]=='='break;
   }
   for (;i<s.size();i++)
   if (s[i]=='|') b++;

   if (abs(a-b)!=2&&a!=b) cout<<"Impossible";
   else
   {
       if (a==b) cout<<s;
       else if (a<b)
       {
           cout<<'|';
           for (int i=0;i<s.size()-1;i++)
           cout<<s[i];
       }
       else
       {
            if (s[1]!='+')
            {
            for (int i=1;i<s.size();i++)
            cout<<s[i];
            cout<<'|';
            }
            else
            {
                cout<<s[0]<<s[1];
                s+='|';
                for (int i=3;i<s.size();i++)
                cout<<s[i];
            }
       }
   }
   cout<<endl;
    return 0;

} 

B:

吐槽的小学奥数题:    A1A2A3A3...AN*X=ANA1A2A3....AN-1;

                              还有个限制就是让满足条件的A1A2A3A4..AN字典序最小

                              方法是:枚举AN,然后保存可行方案,判段一下。。。

                             丑丑的代码:

                              #include<iostream>

#include<math.h>
#include<algorithm>
#include<string>
#include<set>
#include<map>
using namespace std;
int a[2000000];
int b[2000000];
int p,x;

void pan()
{
    int flag=0;
    for (int i=p;i>=1;i--)
    if (b[i]>a[i])
       {
        flag=1;
        break;
    }

    if (flag)
    for (int i=p;i>=1;i--)
        b[i]=a[i];
}

int main()
{

    cin>>p>>x;
    /*if (x==1)
    {
         cout<<1;
          for (int i=1;i<p-1;i++)
            cout<<0;
        if (p>1) cout<<1<<endl;
        return 0;
    }
*/

    for (int i=1;i<=p;i++)
    b[i]=9;

    int flag=0;
    for (int i=9;i>=1;i--)
    {
        int next=i;
        int tem=0;
        for (int j=1;j<=p;j++)
        {
        a[j]=next;
        tem=next*x+tem/10;
        next=tem%10;
    }
    if (tem==i) {if (a[p]!=0&&a[1]!=0) {flag=1;pan();}
    }
}

  if (flag)
  {

   for (int j=p;j>=1;j--)
    cout<<b[j];
  }

  else cout<<"Impossible";
  cout<<endl;
  return 0;

}

   还是比赛快10分钟结束的时候出的,弱。。。。

代码风格不是很好,建议不要看代码了。。。。。。^^

C:

这几天一直在想C,D题,其实题目也很好理解

先初始所有的为“00” 

先从左往右放"11", 

然后放"01","10";后面的就不应管了,程序也相应比较简单,不过自己的编码能力。。。。不吐槽了

#include<iostream>
#include<string>
using namespace std;
string s[1001][1001];
int n,m,sum;
int k;

int main()
{
    cin>>n>>m;
    for (int i=1;i<=n;i++)
      for (int j=1;j<=m;j++)
       {
       cin>>s[i][j];
       if (s[i][j]=="11") k++;
       if (s[i][j][0]=='1') sum++;
       if (s[i][j][1]=='1') sum++;
      }

    //cout<<endl;

     for (int i=1;i<=n;i++)
     for (int j=1;j<=m;j++)
     s[i][j]="00";

     for (int t=1;t<=n;t++)
     for (int i=1;i<=m;i++)
     if (s[t][i]=="00")
        {
         if (k) {s[t][i]="11";k--;sum-=2;}
         else   {
                int y=t;
              //  while (s[y][i]!="00") y++;
                if (sum&&(y<=n)) {s[y][i]="10";sum--;y++;}
                if (sum&&(y<=n)) {s[y][i]="01";sum--;}
              }
     }


      for (int i=1;i<=n;i++)
      {
        for (int j=1;j<m;j++)
        cout<<s[i][j]<<" ";
        cout<<s[i][m]<<endl;
      }
return 0;

}

D题:二分STEP;然后O(N*N) 判断可行性,这里我参考了某位大牛的方法,后来自己也小证明了一下

        [ A[I]-STEP,A[I]+STEP],这是第I个可能达到的值,然后枚举公差,问题的关键是怎样判断是否可行

        假如枚举到公差的D,第N个的数值能达到的是[A[N]-STEP,A[N]+STEP],第N-1个可能的是[A[N-1]-step,A[N-1]+STEP]与[A[N]-STEP-D,A[N]+STEP-D]的交集

于是[MAX(A[N-1]-STEP,A[N]-STEP-D),MIN(A[N-1]+STEP,A[N]+STEP-D)];

CODE:#include<iostream>

#include<math.h>
#include<algorithm>
using namespace std;
int a[2000],n;
int ans,up,down,yy;
int pan(int Max)
{
   for (int d=0;d<=20000;d++)
   {
        up=a[n]+Max;
        down=a[n]-Max;
       for (int i=n-1;i>=1;i--)
       {
          up=min(up-d,a[i]+Max);
          down=max(down-d,a[i]-Max);
       }
         if (down<=up) {
          ans=d;yy=down;
          return 1;}
         }
   return 0;
}
int main()
{
    cin>>n;
    for (int i=1;i<=n;i++)
    cin>>a[i];
    sort(a+1,a+n+1);

     int l=0,r=999999;
     while (l<r)
        {
        int mid=(l+r)/2;
        if (pan(mid)) r=mid;
        else l=mid+1;
    }
    cout<<l<<endl<<yy<<" "<<ans<<endl;
    return 0;

} 

这里是那位大大的BLOG:http://blog.csdn.net/accelerator_/article/details/19670387

比我的详细的好多了 

        

 

     

 

posted on 2014-02-25 17:03  forgot93  阅读(212)  评论(0编辑  收藏  举报

导航