题目链接:点击打开链接
题目大意:八皇后问题,问有多少个逻辑相邻的碰撞?
解题思路:利用一位数组替代二维,因为只有 col、row、mdl(主对角线)、adl(反对角线),这四种情况,看图就明白,如果一行 row 中有 5 个皇后,则该行答案就是 4;其他类似。
注意:从左上至右下的数归为主对角线,从左下至右上的数归为副对角线。
CE 代码(二维数组太大,但思路是对的)
#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a);
#define INF 0x3f3f3f3f
#define MOD 1000000007
using namespace std;
typedef long long ll;
const int maxn=300;
int n,m,l;
ll rs;
int mp[maxn][maxn];
int xr[maxn], yr[maxn];
void jde(int x,int y)
{
// up
for(int i=x-1,f=1;i>=0 && f;i--)
if(mp[i][y]==1) rs++, f=0;
// up-right
for(int i=x-1,j=y+1,f=1;i>=0 && j<=n && f;i--,j++)
if(mp[i][j]==1) rs++, f=0;
// right
for(int j=y+1,f=1;j<=n && f;j++)
if(mp[x][j]==1) rs++, f=0;
// down-right
for(int i=x+1,j=y+1,f=1;i<=n && j<=n && f;i++,j++)
if(mp[i][j]==1) rs++, f=0;
// down
for(int i=x+1,f=1;i<=n && f;i++)
if(mp[i][y]==1) rs++, f=0;
// down-left
for(int i=x+1,j=y-1,f=1;i<=n && j>=0 && f;i++,j--)
if(mp[i][j]==1) rs++, f=0;
// left
for(int j=y-1,f=1;j>=0 && f;j--)
if(mp[x][j]==1) rs++, f=0;
// up-left
for(int i=x-1,j=y-1,f=1;i>=0 && j>=0 && f;i--,j--)
if(mp[i][j]==1) rs++, f=0;
}
void fun()
{
int x,y;
for(int i=0;i<l;i++)
jde(xr[i],yr[i]);
}
int main()
{
int sp,sx,sy,dx,dy;
while(~scanf("%d",&n) && n)
{
scanf("%d",&m); mem(mp,0); rs=l=0;
while(m--)
{
scanf("%d%d%d%d%d",&sp,&sx,&sy,&dx,&dy);
mp[sx][sy]=1; sp--; xr[l]=sx, yr[l]=sy, l++;
while(sp--) mp[sx+=dx][sy+=dy]=1, xr[l]=sx, yr[l]=sy, l++;
}
fun();
printf("%lld\n",rs/2);
}
return 0;
}
AC 代码
#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a);
#define INF 0x3f3f3f3f
#define MOD 1000000007
using namespace std;
typedef long long ll;
const int maxn=600010;
int n,m;
int adl[maxn], mdl[maxn], col[maxn], row[maxn];
int main()
{
int k,sx,sy,dx,dy,x,y;
while(~scanf("%d",&n) && n)
{
mem(adl,0); mem(mdl,0); mem(col,0); mem(row,0);
scanf("%d",&m);
while(m--)
{
scanf("%d%d%d%d%d",&k,&sx,&sy,&dx,&dy);
for(int i=0;i<k;i++)
{
x=sx+dx*i, y=sy+dy*i;
col[y]++;
row[x]++;
mdl[x+y]++;
adl[n+x-y]++;
}
}
ll rs=0;
for(int i=0;i<2*n;i++)
{
if(col[i]>1) rs+=col[i]-1;
if(row[i]>1) rs+=row[i]-1;
if(mdl[i]>1) rs+=mdl[i]-1;
if(adl[i]>1) rs+=adl[i]-1;
}
printf("%lld\n",rs);
}
return 0;
}
扫描二维码关注公众号,回复:
2815469 查看本文章