zoukankan      html  css  js  c++  java
  • SSLOJ 1344 Knights

    题目

       

    Description

      We are given a chess-board of size n*n, from which some fields have been removed. The task is to determine the maximum number of knights that can be placed on the remaining fields of the board in such a way that none of them check each other. 
      一张大小为n*n的国际象棋棋盘,上面有一些格子被拿走了,棋盘规模n不超过200。马的攻击方向如下图,其中S处为马位置,标有X的点为该马的攻击点。 
     
    Fig.1: A knight placed on the field S checks fields marked with x. 
    Write a program, that: 
    reads the description of a chess-board with some fields removed, from the input file kni.in, 
    determines the maximum number of knights that can be placed on the chess-board in such a way that none of them check each other, 
    writes the result to the output file kni.out. 
    你的任务是确定在这个棋盘上放置尽可能多的马,并使他们不互相攻击。 

    Input

    The first line of the input file kni.in contains two integers n and m, separated by a single space, 1<=n<=200, 0<=m<n2; n is the chess-board size and m is the number of removed fields. Each of the following m lines contains two integers: x and y, separated by a single space, 1<=x,y<=n -- these are the coordinates of the removed fields. The coordinates of the upper left corner of the board are (1,1), and of the bottom right are (n,n). The removed fields are not repeated in the file.

    Output

    The output file kni.out should contain one integer (in the first and only line of the file). It should be the maximum number of knights that can be placed on the given chess-board without checking each other.

    Sample Input

    3 2
    
    1 1
    
    3 3
    
    
    

    Sample Output

    5

    分析

        首先,我们要采用黑白描点法

         具体来说,设某个点的位置是i行j列, 那么当[(i+j)%2==0]时,该点为黑色,否则该点为白色。

         

         

         而对于被拿走的格子,我们完全可以认为这些点不存在, 不做任何处理。

         

    代码

     #include<cstdio>
     #include<cstring>
     #include<iostream>
     #include<vector>
     using namespace std;
     long long n,x,y,ans,link[40005],s[205][205],p,ss;
     vector<int> f[40005];
     bool cover[40005],a[205][205];
     int fx[8][2]={{1,2},{1,-2},{2,1},{2,-1},{-1,2},{-1,-2},{-2,1},{-2,-1}};//马的8个方向
    bool find(int i)
    {
         for (int k=0;k<f[i].size();k++)
           if (!cover[f[i][k]])
           {
               int j=f[i][k];
              cover[j]=true;
                 int q=link[j];
              link[j]=i;
                if (q==0||find(q)) return true;
               link[j]=q;
            }
        return false;
    }
    int main()
     {
         cin>>n>>ss;
         for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
          s[i][j]=n*(i-1)+j;
        for (int i=1;i<=ss;i++)
         {
             cin>>x>>y;
           a[x][y]=1;
        }
         
         for (int i=1;i<=n;i++)
         {
             for (int j=1;j<=n;j++)
             {
                 if (!a[i][j]&&(i+j)%2==0)
                 {
                     int ax,ay;
                       for(int kk=0;kk<8;kk++)//8个方向
                       {
                           ax=i+fx[kk][0],ay=j+fx[kk][1];
                           if(ax<1||ax>n||ay<1||ay>n) continue;//判断是否越界
                           if(a[ax][ay]) continue;//判断该可攻击的点是否被移除
                           f[s[i][j]].push_back(s[ax][ay]);//连边
             }
                 }
                    
             }
         }
         int ans=0;
         for (int i=1;i<=n*n;i++)
                 {
                     memset(cover,0,sizeof(cover));
                     ans+=find(i);
                 }    
         
         cout<<n*n-ans-ss;                                     
     }
    为何要逼自己长大,去闯不该闯的荒唐
  • 相关阅读:
    C++小结
    进程
    JavaScript中如何获取当前点击对象信息!
    form表单中enctype="multipart/form-data"的传值问题
    WebMagic框架总结
    工具类:自己总结的利用fileupload包上传文件的工具类!
    工具类:关于如何找到两个List数组中不同的数据的算法!
    工具类:关于解决数据库中的日期格式,经过response.getWriter().write(json)打到前台日期格式混乱的问题的总结
    工具类:将其他编码类型转换成UTF-8或者其他类型的工具类
    博主收藏的前端框架,极力推荐!
  • 原文地址:https://www.cnblogs.com/zjzjzj/p/10123824.html
Copyright © 2011-2022 走看看