Analysis Gym - 101173A UVALive - 7747 Appearance Analysis (模拟)

本文介绍了一种通过分析照片中等尺寸窗户的设计来识别不同图案的方法。利用旋转不变性来确定窗户的独特设计,并通过将每个设计转换为二进制字符串进行比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题:

You have taken a photo of the Faculty of Electrical Engineering and Computing “C” building here
in Zagreb with its equal sized windows neatly arranged in rows and columns. Some of the windows
are painted in curious designs and you are trying to analyze the photo and determine the number of
distinct designs.
We represent the photo as a rectangular grid of characters with r rows and c columns. Every window
is a rectangular area and all windows have the same dimensions. Each cell in a window is either clear
(denoted by the “.” character) or painted (denoted by the “+” character). Two windows are considered
to be of the same design if one can be rotated a multiple of 90 degrees and placed on top of the other
so that they perfectly match. When comparing designs, we are not allowed to flp a window inside out.
Windows are regularly aligned in rows and columns with exactly one row of brick cells (denoted by
the “#” character) framing each window. More precisely, there is a single row of “#” characters between
two consecutive window rows as well as before the fist window row and after the last window row.
Similarly, there is a single column of “#” characters between two consecutive window columns as well
as before the fist window column and after the last window column. The exact number of window
rows and window columns is arbitrary. The window dimensions are also arbitrary. However, a window
consists of at least one cell and, again, all windows in the photo have the same dimensions. Find the
number of diffrent window designs in the photo.
Input
The input fie contains several test cases, each of them as described below.
The fist line contains two integers r and c (3 r, c 111)— number of rows and the number of
columns of the photo. Each of the following r lines contains a string consisting ofccharacters — one
row of the photo.
Output
For each test case, output a single integer on a line by itself — the number of diffrent window designs
in the photo.
Sample Input
11 16
################
#....#++++#+...#
#....#++.+#+...#
#....#.++.#++.+#
#....#....#++++#
################
#....#.+..#++++#
#..++#.+..#++.+#
#+...#....#.++.#
#+...#..++#....#
################
9 21
#####################
#...+#++++#+...#..+.#
#..+.#.++.#.+..#..+.#
#.+..#....#..+.#..+.#
#####################
#.+..#....#..+.#.+..#
#..+.#.++.#.+..#.+..#
#...+#++++#+...#.+..#
#####################
Sample Output
4


每个窗户每个状态转化为01串,求二进制数值,每个数位唯一对应01串即窗户图案


#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <deque>
#include <string>
#include <cmath>
#include <vector>
#include <utility>
#include <set>
#include <map>
#include <sstream>
#include <climits>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define pi acos(-1.0)
#define INF 2147483647
using namespace std;
typedef long long ll;
typedef pair <int,int> P;
int map_[120][120];
char cc;
int r,c;
struct Window
{
    int num[5];
} wind[120*120];
int main ()
{
    while(scanf("%d%d",&r,&c)!=EOF)
    {
        for(int i=0; i<120*120; i++)
            for(int j=0; j<5; j++)
                wind[i].num[j]=0;
        int size_=0,w=0,h=0;
        sizeof(map_,0,sizeof(map_));
        for(int i=0; i<r; i++)
            for(int j=0; j<c; j++)
            {
                cin>>cc;
                if(cc=='#')
                    map_[i][j]=2;
                else if(cc=='.')
                    map_[i][j]=0;
                else
                    map_[i][j]=1;
            }
        for(int i=1; i<r; i++)
        {
            for(int j=1; j<c; j++)
            {
                if(j==1&&map_[i][j]==2)
                {
                    i=r;
                    break;
                }
                if(map_[i][j]==2)
                    break;
                size_++;
                if(i==1)
                    w++;
                if(j==1)
                    h++;
            }
        }
        int num=0;
        int id=0;
        for(int a=1; a<r; a+=(h+1))
            for(int b=1; b<c; b+=(w+1))
            {
                num=0;
                for(int i=0; i<h; i++)
                    for(int j=0; j<w; j++)
                    {
                        num*=2;
                        num+=map_[a+i][b+j];
                    }
                wind[id].num[0]=num;
                id++;
            }
        id=0;
        for(int a=1; a<r; a+=(h+1))
            for(int b=w; b<c; b+=(w+1))
            {
                num=0;
                for(int j=0; j>-w; j--)
                    for(int i=0; i<h; i++)
                    {
                        num*=2;
                        num+=map_[a+i][b+j];
                    }
                wind[id].num[1]=num;
                id++;
            }
        id=0;
        for(int a=h; a<r; a+=(h+1))
            for(int b=w; b<c; b+=(w+1))
            {
                num=0;
                for(int i=0; i>-h; i--)
                    for(int j=0; j>-w; j--)
                    {
                        num*=2;
                        num+=map_[a+i][b+j];
                    }
                wind[id].num[2]=num;
                id++;
            }
        id=0;
        for(int a=h; a<r; a+=(h+1))
            for(int b=1; b<c; b+=(w+1))
            {
                num=0;
                for(int j=0; j<w; j++)
                    for(int i=0; i>-h; i--)
                    {
                        num*=2;
                        num+=map_[a+i][b+j];
                    }
                wind[id].num[3]=num;
                id++;
            }
            for(int i=0;i<id;i++)
                sort(wind[i].num,wind[i].num+4);
//        for(int i=0;i<id;i++)
//            for(int k=0;k<4;k++)
//            cout<<wind[i].num[k]<<endl;
        bool ok[120*120];
        int res=0;
        memset(ok,false ,sizeof(ok));
        for(int i=0; i<id; i++)
        {
           if(ok[i])
            continue;
           for(int j=i+1;j<id;j++)
           {
               for(int k=0;k<4;k++)
                if(wind[i].num[0]==wind[j].num[k])
               {
                   ok[j]=true;
                   break;
               }
           }
        }
        for(int i=0;i<id;i++)
            if(!ok[i])
            res++;
        printf("%d\n",res);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值