首页 > 其他 > 详细

Codeforces Round #234 (Div. 2)

时间:2014-03-06 16:41:16      阅读:798      评论:0      收藏:0      [点我收藏+]

CF 400A. Inna and Choose Options

题目链接:
http://codeforces.com/problemset/problem/400/A

题目意思:
给只含‘X‘和’O‘字符的长度为12的字符串,将它写入矩阵a*b(a*b=12)中,问存在某一列全为‘X‘的矩阵的个数。

解题思路:
枚举。一共只有1*12,2*6,3*4,4*3,6*2,12*1六种。

代码:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

char save[25];
int a[10]={0,1,2,3,4,6,12}; //保存六种情况
vector<int>myv;

int main()
{
   //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);
   int t;

   scanf("%d",&t);
   while(t--)
   {
       myv.clear();
       scanf("%s",save+1);

       int ans=0;

       for(int i=1;i<=6;i++)
       {
           int aa=a[i];
           int bb=12/a[i];

           bool flag=false;

           for(int j=1;j<=bb;j++)
           {
               bool tt=true;
               for(int k=1;k<=aa;k++)
               {
                   if(save[(k-1)*bb+j]!=‘X‘)
                   {
                       tt=false;
                       break;
                   }
               }
               if(tt)
               {
                   flag=true;
                   break;
               }

           }
           if(flag)
           {
               ans++;
               myv.push_back(a[i]);//保存结果集
           }
       }
       printf("%d ",ans);
       for(int i=0;i<myv.size();i++)
            printf("%dx%d ",myv[i],12/myv[i]);
       putchar(‘\n‘);


   }
   return 0;
}






CF 400B. Inna and New Matrix of Candies

题目链接:

http://codeforces.com/contest/400/problem/B

题目意思:

给n*m的方格,每行中都且仅有一个方格含S和G,每一步可以使所有的G向右移,只到发生下列情况:1、某个G已到了最后一列。2、某个G已到了S。求把所有的G已到S需要的最少的步数。

解题思路:

统计S-G差出现的个数。

代码:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define Maxn 1100

char save[Maxn][Maxn];
int n,m;
int gap[Maxn];

int main()
{
   //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);
   while(~scanf("%d%d",&n,&m))
   {
       bool flag=true;

       memset(gap,0,sizeof(gap));

       for(int i=1;i<=n;i++)
       {
           scanf("%s",save[i]+1);
           int g,s;
           for(int j=1;j<=m;j++)
           {
               if(save[i][j]==‘G‘)
                    g=j;
               else if(save[i][j]==‘S‘)
                    s=j;

           }
           if(g>s)
                flag=false;
           else
                gap[s-g]++;

       }

       if(!flag)
       {
           printf("-1\n");
           continue;
       }
       int ans=0;

       for(int i=1;i<=m;i++)
            if(gap[i])
                ans++;
       printf("%d\n",ans);
   }
   return 0;
}

CF 400C C. Inna and Huge Candy Matrix

题目链接:

http://codeforces.com/problemset/problem/400/C

题目意思:

给一个矩阵,求经过顺时针旋转90度x次,左右翻转y次,逆时针旋转90度z次,坐标(x,y)对应的新坐标。

解题思路:

上面三种变换可以统一成几个简单的基本操作。详细可以参考我的这篇博客:http://blog.csdn.net/cc_again/article/details/18007891

这题相对比较简单,可以先对x%=4,y%=2,z=(4-z%4)%4(转化成顺时针的情况),然后对于每个坐标,分别实行上述操作,即可得到答案。

代码:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

int n,m;
int tempn,tempm;

void C90(int &x,int &y) //顺时针旋转90度
{
    int temp=x;

    x=y;
    y=tempn-temp+1;

    swap(tempn,tempm);
}
void hh(int &x,int &y) //左右翻转
{
    y=tempm-y+1;
}
int main()
{
   //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);
   int x,y,z,p;

   while(~scanf("%d%d",&n,&m))
   {
       scanf("%d%d%d%d",&x,&y,&z,&p);
       x=x%4; //顺时针的次数
       z=(4-z%4)%4; //转化为顺时针的次数
       y=y%2; //左右翻转

       for(int i=1;i<=p;i++)
       {
           int a,b;

           scanf("%d%d",&a,&b);
           tempn=n,tempm=m;

           for(int i=1;i<=x;i++)
                C90(a,b);
           if(y)
               hh(a,b);

           for(int i=1;i<=z;i++)
               C90(a,b);
           printf("%d %d\n",a,b);



       }

   }

   return 0;
}

CF 400 E E. Inna and Binary Logic

题目链接:

http://codeforces.com/problemset/problem/400/E

题目意思:

给定n个数a1[1..n],定义ak[i]=ak-1[i]&ak-1[i+1],则一共有n*(n-1)/2个数。有m种操作,每种操作ai,bi,表示把a1[ai]改成bi,求这n*(n-1)/2个数的和,改变是连续影响的。

解题思路:

二进制和数据结构。

按位进行处理,mys[i]表示第i位为零是n个数中的哪几个。两个零之间一定是连续的1,扫描开始的n个数,对于每一位如果它为1,则找到大于它的第一个为0的位置,则这个1持续的次数就是他们之间的间隔。这样求出原始的总和。

操作主要分两种:

1、把当前位的0变成1。此时从当前的0到下一个0的间距是该位0所要增加的1的个数p,该零后面的将不受影响。该零前面的所有连续的1(假设为m个)都会增加p个。(从0往左下角45度对角线)故+m*p*位权。

2、把当前位的1变成0。与上述情况相反,-m*p*位权。

注意要连续更新原始数组,中间溢出情况。

代码:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define Maxn 110000
set<int>mys[20]; //mys[i]保存第i位为零有哪几个数
int save[Maxn];

int main()
{
    //cout<<(1<<20);
   //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);
   int n,m;

   while(~scanf("%d%d",&n,&m))
   {
       for(int i=0;i<20;i++)
       {
           mys[i].clear();
           mys[i].insert(0); //边界情况考虑进去
           mys[i].insert(n+1);
       }
       for(int i=1;i<=n;i++)
       {
           scanf("%d",&save[i]);
           for(int j=0;j<20;j++)
           {
               if(!(save[i]&(1<<j)))
                    mys[j].insert(i); //统计j位为0的 哪几个情况
           }

       }
       ll ans=0;

       for(int i=1;i<=n;i++)
       {
           for(int j=0;j<20;j++)
           {
               if(save[i]&(1<<j)) //非零的情况
               {
                   set<int>::iterator it=mys[j].upper_bound(i); //找到大于当前位置的第一个零的位置

                   ans+=(ll)(*it-i)*(1<<j);
               }
           }
       }
       //printf("%I64d\n",ans);
       //system("pause");

       for(int i=1;i<=m;i++)
       {
           int ri,va;

           scanf("%d%d",&ri,&va);

           for(int j=0;j<20;j++)
           {
               if((va&(1<<j))&&((save[ri]&(1<<j))==0)) //要把0改成1
               {
                   set<int>::iterator it=mys[j].find(ri);

                   it++;
                   int rr=*it;
                   it--;
                   it--;
                   int le=*it;

                   ans+=(ll)(rr-ri)*(1<<j)*(ri-le);

                   mys[j].erase(ri);
               }
               else if(((va&(1<<j))==0)&&(save[ri]&(1<<j))) //把1变成0
               {
                   mys[j].insert(ri);
                   set<int>::iterator it=mys[j].find(ri);

                   it++;
                   int rr=*it;
                   it--;
                   it--;
                   int le=*it;

                   ans-=(ll)(rr-ri)*(1<<j)*(ri-le);


               }

           }
           printf("%I64d\n",ans);
           save[ri]=va; //注意连续更新
       }


   }


   return 0;
}





Codeforces Round #234 (Div. 2),布布扣,bubuko.com

Codeforces Round #234 (Div. 2)

原文:http://blog.csdn.net/cc_again/article/details/20616619

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!