BZOJ2241 [SDOI2011]打地鼠 题解&代码

题意:给你一个m*n的方格(初始每个位置都大于0),你可以选择一个固定大小不可旋转的方块(例如大小为x*y),使每次这个方块在方格上某个所有位置都非0的区域覆盖一次时区域内每个位置的值减一,问覆盖多少次后这个方格内部的值全部为0(因为有1*1的方块,所以一定有解)
题解:看起来乱七八糟的,但其实就是个暴力搜索,内部测试的时候因为一些问题看错了m和n,不然就1A了…

/************************************************************** Problem: 2241 User: Rainbow6174 Language: C++ Result: Accepted Time:116 ms Memory:1680 kb ****************************************************************/

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
pair <int,int> q[10005];
int n,m,x,sum,ans,flag=1,tans,map[205][205];
int tot,tmap[205][205];
bool work(int tx,int ty)
{
    int val = 0,temp,flag;
    for(int i = 1; i <= m; i++)
        for(int j = 1; j <= n; j++)
        {
            tmap[i][j]=map[i][j];
            //cout<<tmap[i][j]<<' ';
            //if(j==n)cout<<endl;
        }
    for(int i = 1; i <= m; i++)
        for(int j = 1; j <= n; j++)
        {
            if(!tmap[i][j])continue;
            temp = tmap[i][j];
            flag = 0;
            for(int x = 0; x < tx; x++)
            {
                for(int y = 0; y < ty; y++)
                    if(tmap[i+x][j+y]-temp<0) 
                    {
                        //if(tx==2 && ty == 1)cout<<i<<' '<<j<<' '<<x<<' '<<y<<' '<<tmap[i+x][j+y]<<' '<<temp<<endl;
                        return false;
                    }
                    else tmap[i+x][j+y]-=temp;
            }
        }
    return true;
}
bool cmp(pair<int,int> a,pair<int,int> b)
{
    return (a.first)*(a.second)>(b.first)*(b.second);
}
void slove(void)
{
    for(int i = 1; i <= m; i++)
        for(int j = 1; j <= n; j++)
            q[tot++] = make_pair(i,j);
    sort(q,q+tot,cmp);
    for(int i = 0; i < tot; i++)
        if(sum%((q[i].first)*(q[i].second)) == 0)
        {
            tans = sum/((q[i].first)*(q[i].second));
            //cout<<q[i].first<<' '<<q[i].second<<' '<<tans<<endl; 
            if(work(q[i].first,q[i].second))
            {
                ans = tans;
                break;
            }
        }
}
int main(void)
{
    //freopen("shrew.in","r",stdin);
    //freopen("shrew.out","w",stdout);
    scanf("%d%d",&m,&n);
    for(int i = 1; i <= m; i++)
        for(int j = 1; j <= n; j++)
        {
            scanf("%d",&x);
            if(!x) continue;
            map[i][j] = x;
            sum += x; 
        }
    ans = sum;
    slove();
    printf("%d\n",ans);
    return 0;
}

你可能感兴趣的:(搜索)