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; }
题目链接:
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; }
题目链接:
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