kuangbin OJ 1217-- Operations on Grids(YY)(好题)

来源:互联网 发布:投资日记软件 编辑:程序博客网 时间:2024/05/19 03:17

1217: Operations on Grids

Time Limit: 2 Sec  Memory Limit: 128 MB
Submit: 89  Solved: 20
[Submit][Status][Web Board]

Description

你有一个 9 位数字串,现在你把这个数字的每一位填到 3 × 3 格子上。如果数 字是 123456789,那么填到 3 × 3 格子上会得到: 123 

             456 
             789 
现在你可以对这 3 × 3 格子做四种操作:

现在给你这个 9 位数字串,你需要做 次左旋转操作, 次右旋转操作,  横向翻转操作, 次纵向翻转操作,这些操作之间的先后顺序随便你定。 问最终能得到多少种不同的 3 × 3 格子。两个 3 × 3 格子视为不同,当且仅当 格子中存在至少有一个位置上的数字不同。



Input

输入第一行是一个整数 T,表示有 组数据。 每组数据有两行。第一行为一个 9 位的数字串。第二行包含 4 个整数 ab
(0 <= abc<= 2)


Output

对于每组测试数据,输出一个整数表示最终能得到多少种不同的 3 × 3 格子。


Sample Input

10000000001 2 1 2

Sample Output

1

HINT




思路:由于a,b,c,d较小,直接dfs也可,不过多YY也蛮开心的

YY后的结论:


c,d唯一的作用是:
1.如果c,d是0,那么解只有一种情况
2.c,d其中一个不是0
当翻面后,a其实变成右转,b其实变成左转,所以,当c,d某一个不为0可以让a,b互相贡献,想贡献多少就贡献多少(不超过a,b自身)仅取决与何时翻面


当图上下左右对称那么解是1

当图中心对称那么左旋2次和4次相同

就这三种情况:

// 1312 KB 0 MSC++ 1491 B 2015-03-21 23:04:38#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;char num[15];bool vis[5];int main(){    int T;    scanf("%d",&T);    while(T--)    {        int ans=0;        bool flag=0;        memset(vis,0,sizeof(vis));        scanf("%s",num+1);        int a,b,c,d;        scanf("%d%d%d%d",&a,&b,&c,&d);        if(num[1]==num[3]&&num[7]&&num[9]&&num[3]==num[7]&&num[2]==num[4]&&num[4]==num[6]&&num[6]==num[8])        {            printf("1\n");            continue;        }        if(c==0&&d==0) {            printf("1\n");            continue;        }        if(num[4]==num[6]&&num[2]==num[8]&&num[1]==num[9]&&num[3]==num[7]) flag=1;        int s=a-b;        if(!vis[(s+4)%4])        {            ans++;            vis[(s+4)%4] = true;            if(flag)vis[(s+2)%4] =true;        }        for(int i=1;i<=b;i++)        {            s+=2;            if(!vis[(s+4)%4]) ans++;            vis[(s+4)%4] = true;            if(flag) vis[(s+2)%4]=true;        }        s=a-b;        for(int i=1;i<=a;i++)        {            s-=2;            if(!vis[(s+8)%4]) ans++;            vis[(s+8)%4]=true;            if(flag) vis[(s+10)%4]=true;        }        printf("%d\n",ans);    }    return 0;}



0 0