Bull in a China Shop USACO - 640

发布时间 2023-06-11 02:56:23作者: Cruzz

题目链接:http://www.usaco.org/index.php?page=viewproblem2&cpid=640&lang=en

题意:有一个完整的图形被切分成k个碎片。在k个碎片中,一定有2个碎片可以正好拼成完整的图形。拼接时只能横向竖向移动碎片,并且碎片不能重叠。按顺序输出可以拼出完整图形的2个碎片的序号(第一个碎片序号为1 第二个为2 以此类推)

输入格式:输入n,k,n*n (3≤n≤8) 大小,由“#”和“.”构成的完整图形(“#”代表图形 “.”代表空白 2个碎片空白的地方可以重叠),k个n*n的碎片 具体可看输入样例

思路:枚举选取碎片a,碎片b,枚举碎片a坐标,枚举碎片b坐标,将碎片a,b输入一个空矩阵拼接并与完整图形对比

易错点:循环复杂;注意枚举时候左边范围2*n,矩阵大小4*n

注意点:1. 做任何数组遍历和取值,考虑数组越界

    2. 尽量使用有意义的变量名代替ijk

未满分代码(7/10):

#include<bits/stdc++.h>
#define __NARG__(...) __NARG_I_(__VA_ARGS__, __RSEQ_N())
#define __NARG_I_(...) __ARG_N(__VA_ARGS__)
#define __ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, \
                _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42,  \
                _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62,  \
                _63, N, ...) N
#define __RSEQ_N()                                                                                                    \
  63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, \
      34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, \
      5, 4, 3, 2, 1, 0
#define _VFUNC_(name, n) name##n
#define _VFUNC(name, n) _VFUNC_(name, n)
#define VFUNC(func, ...) _VFUNC(func, __NARG__(__VA_ARGS__))(__VA_ARGS__)
#define show(...) VFUNC(show, __VA_ARGS__)
#define show1(x) cout << #x << "=" << x << endl
#define show2(x, y) cout << #x << "=" << x << " " << #y << "=" << y << endl
#define show3(x, y, z) cout << #x << "=" << x << " " << #y << "=" << y << " " << #z << "=" << z << endl
#define show4(w, x, y, z) cout << #w << "=" << w << " " << #x << "=" << x << " " << #y << "=" << y << " " << #z << "=" << z << endl
#define show5(v, w, x, y, z) cout << #v << "=" << v << " " << #w << "=" << w << " " << #x << "=" << x << " " << #y << "=" << y << " " << #z << "=" << z << endl
#define showa(a, b) cout << #a << '[' << b << "]=" << a[b] << endl
#define showa2(x, a, b) cout << #x << ": "; rep(i, a, b) cout << x[i] << ' '; cout << endl
using namespace std;
char x;
int a[17][17][17],flag;
int f[50][50];
int n,k;
int main(){
//    freopen("bcs.in","r",stdin);
//    freopen("bcs.out","w",stdout);
    //输入 
    cin>>n>>k;
    for(int i=0;i<k+1;i++){
        for(int j=0;j<n;j++){
            for(int k=0;k<n;k++){
                cin>>x;
                if(x=='#'){
                    a[i][j][k]=1;            
                }
            }
        }
    }
    for(int i=1;i<k;i++){//枚举可能的a碎片 顶点a[i][0][0]
        for(int j=i+1;j<k+1;j++){//枚举可能的b碎片 顶点a[j][0][0]
            for(int ax=0;ax<2*n;ax++){//a碎片坐标 
                for(int ay=0;ay<2*n;ay++){
                    for(int bx=0;bx<2*n;bx++){//b碎片坐标 
                        for(int by=0;by<2*n;by++){
                            for(int x=0;x<4*n;x++){//矩阵清空 
                                for(int y=0;y<4*n;y++){
                                    f[x][y]=0;
                                }
                            }
                            for(int x=0;x<n;x++){//把a碎片输入到矩阵 
                                for(int y=0;y<n;y++){
                                    f[x+ax][y+ay]=a[i][x][y];
                                }
                            }
                        /*    show(ax,ay,bx,by);
                            for(int x=0;x<4*n;x++){
                                    for(int y=0;y<4*n;y++){
                                        cout<<f[x][y];
                                    }
                                    cout<<endl;
                                }*/
                            flag=0;
                            for(int x=0;x<n;x++){//把b碎片输入到矩阵 进行拼接以及与完整图形的对比 
                                for(int y=0;y<n;y++){
                                    if(a[j][x][y]==1&&f[x+bx][y+by]==1){//把b拼接到a后面 如果2个都是#就表示不能这样拼 
                                        flag=1;
                                        break;
                                    }
                                    if(a[j][x][y]==1&&f[x+bx][y+by]==0)//只有#能覆盖. 
                                        f[x+bx][y+by]=a[j][x][y];
                                }
                                if(flag==1){
                                    break;
                                }
                            }
                            if(flag==1){
                                continue;
                            }
                        //    show(ax,ay,bx,by);
                        //    if(i==1&&j==3){
                        //        for(int x=0;x<2*n;x++){
                        //            for(int y=0;y<2*n;y++){
                        //                cout<<f[x][y];
                        //            }
                        //            cout<<endl;
                        //        }
                        //    }
                            for(int x2=0;x2<n;x2++){
                                for(int y2=0;y2<n;y2++){
                                    int flag3=0;
                                    for(int x=0;x<n;x++){
                                        for(int y=0;y<n;y++){
                                            if(a[0][x][y]!=f[x2+x][y2+y]){
                                                flag3=1;
                                                break;
                                            }
                                        }
                                        if(flag3==1){
                                            break;
                                        }
                                    }
                                    if(flag3==0){
                                        cout<<i<<" "<<j<<endl;
                                        return 0;
                                    }
                                }
                            }
                            
                        }
                    }
                }
            }
        }
    }
    return 0;
}

/*
测试数据

6 6
......
..#...
..###.
..###.
..###.
...##.

......
...#..
...#..
....#.
.....#
....##

......
......
###...
.#....
..#...
.#....

...#..
...#.#
.....#
...##.
......
......

......
#.....
#.#...
#.#...
.#....
......

......
......
.#....
.#....
#.#...
.##...

...#..
...#..
....#.
....##
....#.
......

5 4
.....
..##.
.###.
.##..
.#...

.....
....#
..##.
..#..
.....

.##..
..#..
.....
#....
.....

.....
...#.
....#
...#.
..#..

.....
...#.
..##.
..#..
.....

6 6
......
..#...
..###.
..###.
..###.
...##.
......
...#..
...#..
....#.
.....#
....##
......
......
###...
.#....
..#...
.#....
...#..
...#.#
.....#
...##.
......
......
......
#.....
#.#...
#.#...
.#....
......
......
......
.#....
.#....
#.#...
.##...
...#..
...#..
....#.
....##
....#.
......
 
4 3
...#
...#
...#
...#

...#
...#
....
....

....
....
....
....

#...
#...
....
....
*/