• P2105 K皇后


    小 Z 最近捡到了一个棋盘,他想在棋盘上摆放 K 个皇后。他想知道在他摆完这 K 个皇后之后,棋盘上还有多少个格子是不会被攻击到的。

    注意:一个皇后会攻击到这个皇后所在的那一行,那一列,以及两条对角线。

    输入格式

    第一行三个正整数 n,m,K,表示棋盘的行列,以及小 Z 摆放的皇后的个数。

    接下来 K 行,每行两个正整数 x,y,表示这个皇后被摆在了第 x行,第 y 列,数据保证任何两个皇后都不会被摆在同一个格子里。

    输出格式

    仅一个整数,表示棋盘上还有多少个格子是不会被攻击到的。

    输入输出样例

    输入 #1复制

    12 13 6
    10 4
    12 10
    1 1
    2 3
    3 2
    2 6

    输出 #1复制

    25

    说明/提示

    • 对于 30\%30% 的数据,1\le n,m\le 5\times10^31≤n,m≤5×103,1\le K\le 5001≤K≤500;
    • 对于另外 10\%10% 的数据,K=1K=1;
    • 对于 100\%100% 的数据,1\le n,m\le 2\times 10^41≤n,m≤2×104,1\le K\le 5001≤K≤500。

     

    我的思路是深搜,超时,看了网上代码,就是优化暴力,有个数学知识的点还没搞懂,代码以理解

    超时代码 

    1. #include <iostream>
    2. using namespace std;
    3. const int N=30000,M=30000;
    4. struct node{
    5. int first,second;
    6. }a[505];
    7. int dx[8]={0,0,1,1,1,-1,-1,-1},dy[8]={1,-1,0,1,-1,0,1,-1};
    8. int n,k,m,ans;
    9. bool s[N][M];
    10. void dfs(int x,int y,int kk){
    11. int xx=x+dx[kk],yy=y+dy[kk];
    12. if(xx>=1&&xx<=n&&yy>=1&&yy<=m){
    13. s[xx][yy]= true;
    14. dfs(xx,yy,kk);
    15. }
    16. return;
    17. }
    18. int main(){
    19. scanf("%d%d%d",&n,&m,&k);
    20. for(int i=1;i<=k;i++){
    21. scanf("%d%d",&a[i].first,&a[i].second);
    22. s[a[i].first][a[i].second]= true;
    23. }
    24. for(int i=1;i<=k;i++){
    25. for(int j=0;j<8;j++){
    26. int x=a[i].first+dx[j],y=a[i].second+dy[j];
    27. s[x][y]= true;
    28. dfs(x,y,j);
    29. }
    30. }
    31. for(int i=1;i<=n;i++){
    32. for(int j=1;j<=m;j++) {
    33. printf("%d ",s[i][j]);
    34. }
    35. printf("\n");
    36. }
    37. for(int i=1;i<=n;i++){
    38. for(int j=1;j<=m;j++){
    39. if(s[i][j]==0){
    40. ans++;
    41. }
    42. }
    43. }
    44. printf("%d\n",ans);
    45. }

     网上ac代码

    1. #include<bits/stdc++.h>
    2. using namespace std;
    3. int x[501],y[501],n,m,k;
    4. int flag[20001],vis[20001],sum,ans;
    5. int main()
    6. {
    7. cin>>n>>m>>k;
    8. for(int i=1;i<=k;i++) cin>>x[i]>>y[i],vis[x[i]]=1;
    9. for(int i=1;i<=n;i++)
    10. {
    11. if(vis[i]) continue;//当前行有国王直接跳过
    12. sum=m;
    13. for(int j=1;j<=k;j++)
    14. {
    15. if(flag[y[j]]!=i) sum--;//当前国王控制的列数
    16. flag[y[j]]=i;
    17. if(x[j]<i)//当前国王在当前行上方
    18. {
    19. if(y[j]+i-x[j]>=1&&y[j]+i-x[j]<=m)
    20. {//右下方向对角线
    21. if(flag[y[j]+i-x[j]]!=i) sum--;
    22. flag[y[j]+i-x[j]]=i;
    23. }
    24. if(y[j]-i+x[j]>=1&&y[j]-i+x[j]<=m)
    25. {//左下方向对角线
    26. if(flag[y[j]-i+x[j]]!=i) sum--;
    27. flag[y[j]-i+x[j]]=i;
    28. }
    29. }
    30. else //当前国王在当前行下方
    31. {
    32. if(y[j]+(x[j]-i)>=1&&y[j]+(x[j]-i)<=m)
    33. {//右下方向对角线
    34. if(flag[y[j]+(x[j]-i)]!=i) sum--;
    35. flag[y[j]+(x[j]-i)]=i;
    36. }
    37. if(y[j]-(x[j]-i)>=1&&y[j]-(x[j]-i)<=m)
    38. {//左下方向对角线
    39. if(flag[y[j]-(x[j]-i)]!=i) sum--;
    40. flag[y[j]-(x[j]-i)]=i;
    41. }
    42. }
    43. }
    44. ans+=sum;
    45. }
    46. cout<<ans;
    47. }

  • 相关阅读:
    Delphi11.3FMX微信支付到个人账户源代码(手机POS机安卓源代码、手机APP收款机苹果源代码、PC源代码)
    Matlab:解决错误:未定义的函数或变量
    【scikit-learn基础】--『监督学习』之 层次聚类
    时序分析 42 -- 时序数据转为空间数据 (一) 格拉姆角场
    git使用
    云原生中间件RocketMQ-生产者核心解析、主从同步机制解析,生产者同步异步消息发送
    JVM-0522
    【咖啡品牌分析】Google Maps数据采集咖啡市场数据分析区域分析热度分布分析数据抓取瑞幸星巴克
    JVM学习-监控工具(一)
    Win11笔记本省电模式怎么开启?Win11电脑节电模式打开方法
  • 原文地址:https://blog.csdn.net/q619718/article/details/127718662