codeforces 400A - Inna and Choose Options

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





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值