ural1006 Square Frames

不说了先上那个我找了好久翻墙才找到的图

(题里的图)

只有后画的框框是可见的,顺序只要合理即可

先是有几个框框,,然后是左上角的坐标,,最后是长为多少(横着的),,,,题意就是这样,,看起来也不难想,,但是应该比较容易超时。。。。。。

我再读读题,,,突然发现,,,我擦这题的输入就很狗啊。。。直接输入一个图有木有。。。。。。前面给ascii码果然有用。。。。。。

这题应该就是纯模拟吧,,,,,,也没有太好的办法,,主要是注意模拟的方法,,,,,先是找到左上角,然后遍历一圈看是不是都显示了出来,遍历成功一个就把他所有的点都变成 点 就好(因为不存在残缺的矩形,,) ,也就是说之后的遍历只要没遇到角,遇到 点 也算是边(当然不写成点换一个符号也可以,,都是一样的,,,遍历完了就拉倒)。。。。。就是这样。。。。。。


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include<bits/stdc++.h>
using namespace std;

struct answer{int i,j,k;};
vector<answer>ans;
unsigned char G[21][51];
int yes(int i,int j,int k)
{
    int x,ans=0;
    if(G[i][j]!=48&&G[i][j]!=218||G[i][j+k]!=48&&G[i][j+k]!=191||G[i+k][j]!=48&&G[i+k][j]!=192||G[i+k][j+k]!=48&&G[i+k][j+k]!=217)  return 0;  //如果不是左上角或者有一条边的长度不对就返回
    for(x=1;x<k;x++){
        if(G[i][j+x]!=48&&G[i][j+x]!=196||G[i+k][j+x]!=48&&G[i+k][j+x]!=196||G[i+x][j]!=48&&G[i+x][j]!=179||G[i+x][j+k]!=48&&G[i+x][j+k]!=179)  break;//如果不是点也不是横或竖
        if(!ans&&(G[i][j+x]==196||G[i+k][j+x]==196||G[i+x][j]==179||G[i+x][j+k]==179))  ans=1; //如果是横竖就标记一下
    }
    if(x<k)  return 0;          //x==k 之前跳出说明有的不符合条件
    if(!ans&&(G[i][j]==218||G[i][j+k]==191||G[i+k][j]==192||G[i+k][j+k]==217))  ans=1; //最后一次跳出了但是还是符合条件了(就是一直没有不是点的存在)
    return ans;                 //到底是不是
}
int f5(int i,int j,int k)
{
    int x,ans=0;
    for(x=0;x<=k;x++)         //全变成点,,然后返回变了多少个点(角也变)
    {
        if(G[i][j+x]!=48)    ans++,G[i][j+x]=48;
        if(G[i+k][j+x]!=48)  ans++,G[i+k][j+x]=48;
        if(G[i+x][j]!=48)    ans++,G[i+x][j]=48;
        if(G[i+x][j+k]!=48)  ans++,G[i+x][j+k]=48;
    }
    return ans;
}
int main()
{
    //freopen("URAL 1006.txt","r",stdin);
    int i,j,k,np=0,t;
    for(i=0;i<20;i++){
        for(j=0;j<50;j++){
            G[i][j]=getchar();  //很不建议用getchar的,,在有的oj上面会出错//
            np+=G[i][j]==46?0:1;  //记录下来一共有多少个不是点
        }
        getchar();  //将回车读取掉
    }
    while(np)      //还没遍历完
    {
        t=np;
        for(i=0;i<20;i++)
            for(j=0;j<50;j++)
                for(k=1;i+k<20&&j+k<50;k++)   //k表示边长,,这里就是不能超出
                    if(yes(i,j,k))
                        np-=f5(i,j,k),ans.push_back(answer{j,i,k+1});  //数据结构呜呜呜
        if(np==t)  break;      //如果遍历一次发现没有左上角了。。。。。
    }
    printf("%d\n",ans.size());
    for(i=ans.size()-1;~i;i--)
        printf("%d %d %d\n",ans[i].i,ans[i].j,ans[i].k);
    return 0;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值