海战游戏

在N*M的矩阵上,放置了L个军舰,军舰的左上角坐标为ux,uy,左下角坐标为dx,dy。军舰是一个矩形。现在要放置第L+1个军舰,但是军舰不能重叠,并且上下左右,上左,上右,下左,下右都不能相邻。求放置一个长为p,宽为q的军舰的放置方案数(放置方案)。

2<=N,M<=30000,L<=30;

 

朴素的方法。对军舰可以放置的位置进行枚举,并且判断每一个位置是否与其他军舰冲突。时间复杂度为O(MNL)

 

补集的方法。计算所有冲突的位置,用总放置方法减去,就是我们可以放的地方。时间复杂度为(p^2*q^2*L^2)军舰大小远远小于M,N,

该方法提高了时间效率

 

代码如下

#ifndef SeaWar_H #define SeaWar_h #include struct ShipType { int ux,uy,dx,dy; }; class SeaWar { ShipType **ships; int n,m,l; int p,q; public: SeaWar() { std::cin>>n>>m>>l; ships=new ShipType*[l+2]; for(int i=1;i<=l;i++) { ships[i]=new ShipType; std::cin>>ships[i]->ux>>ships[i]->uy>>ships[i]->dx>>ships[i]->dy; } std::cin>>p>>q; int ans=(n-p+1)*(m-q+1); bool tempBool=false; for(int i=1;i<=l;i++) { for(int x=max(ships[i]->ux-p,1);x<=min(ships[i]->dx+1,n-p+1);x++) { for(int y=max(ships[i]->uy-q,1);y<=min(ships[i]->dy+1,m-q+1);y++) { tempBool=true; for(int j=1;jux,ships[j]->uy,ships[j]->dx,ships[j]->dy)) { tempBool=false; break; } } if(tempBool) { if(check(x,y,x+p-1,y+q-1,ships[i]->ux,ships[i]->uy,ships[i]->dx,ships[i]->dy)) { ans--; } } } } } std::cout<=ax1-1)&&(by1<=ay2+1)&&(by2>=ay1-1); } int min(int a,int b) { return ab?a:b; } }; #endif

你可能感兴趣的:(算法,补集转换,算法题目)