题目链接:http://codeforces.com/problemset/problem/400/A
题目大意:n行12列的字符串,每行检查,若将一行拆成a行b列后,至少有1列全部是‘X’的话就赢得游戏,问有几种方案,并打印出来。
其实如果你学过密码,听说过栅栏密码的话,那应该就很清楚了,如果有疑惑的话,再以样例解释一下——
4
OXXXOXOOXOOX
OXOXOXOXOXOX
XXXXXXXXXXXX
OOOOOOOOOOOO
共4行字符串,每行12个字符,第一行“OXXXOXOOXOOX”:
1*12:OXXXOXOOXOOX,yes
2*6:OXXXOX
-----OOXOOX,yes
3*4:OXXX
-----OXOO
-----XOOX,no
4*3:OXX
-----XOX
-----OOX
-----OOX,yes
6*2:……,no
12*1:……,no
题目分析:模拟
代码参考:
(一)我的版本
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long LL;
const int N = 20;
char s[N];
int a[N], ans[N], sum[N];
bool ok(int n)
{
memset(sum, 0, sizeof(sum));
int i;
for(i=1; i<=12; ++i) sum[i%n] += a[i];
for(i=0; i<n; ++i) if(sum[i] == 12/n) return true;
return false;
}
int main()
{
int n, m, i, j, k, cnt;
while(~scanf("%d", &n))
{
while(n--)
{
scanf("%s", s+1);
for(i=1; i<=12; ++i)
{
if(s[i] == 'O') a[i] = 0;
else a[i] = 1;
}
cnt = 0;
for(i=12; i>=1; --i)
{
if(12%i) continue;
if(ok(i))
{
ans[cnt++] = i;
}
}
printf("%d ", cnt);
for(i=0; i<cnt; ++i) printf("%dx%d ", 12/ans[i], ans[i]);
puts("");
}
}
return 0;
}
(二)小土豆的版本(应该写得比我好的样子……)
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cstdio>
#include<string>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
const int N = 11;
char s[22][22], tmp[22];
vector<int> as;
int main() {
int i, j, k, re, ri, a, b;
scanf("%d", &re);
for(ri=1; ri<=re; ++ri) {
as.clear();
scanf("%s", tmp);
for(a=1; a<=12; ++a) {
if(12%a) continue;
b=12/a;
int id=0;
for(i=0; i<a; ++i) {
for(j=0; j<b; ++j) {
s[i][j]=tmp[id++];
}
}
bool ok=false;
for(j=0; j<b; ++j) {
bool f=true;
for(i=0; i<a; ++i) {
if(s[i][j]!='X') {
f=false;
}
}
if(f) {
ok=true;
}
}
if(ok) {
as.push_back(a);
}
}
cout<<as.size();
for(vector<int>::iterator ai=as.begin(); ai<as.end(); ++ai) {
cout<<" "<<*ai<<"x"<<12/(*ai);
}
cout<<endl;
}
return 0;
}