“传教士问题”

转载请写明出处:http://blog.csdn.net/big_heart_c

本题的思路是使传教士们所占用的传教区域重叠,即找出每个传教士的对角线上还没被占用的点的数目最少。

代码如下:

[cpp]  view plain copy
  1. //From Big Heart  
[cpp]  view plain copy
  1. //传教士  
  2. #include <iostream>  
  3. using namespace std;  
  4. int find_min(int i,int j);  
  5. void change(int i,int j);  
  6. int a[20][20];  
  7. int n,m;    //4行3列  
  8. int main(){  
  9.     int min_ = 400,i_=21,j_=21,timer = 0;  
  10.     memset(a,0,sizeof(a));  
  11.     cin >> n >> m;  
  12.     bool isContinue = false;  
  13.     do{  
  14.     isContinue = false;  
  15.     for(int i=0;i<m;i++)  
  16.         for(int j=0;j<n;j++){  
  17.             if(a[i][j] == 0){  
  18.                 isContinue = true;  
  19.                 int temp = find_min(i,j);  
  20.                 if(min_>temp){  
  21.                     min_ = temp;  
  22.                     i_=i,j_=j;  
  23.                 }  
  24.             }  
  25.         }  
  26.         change(i_,j_);  
  27.         timer++;  
  28.         min_ = 400;  
  29.     }while(isContinue);  
  30.     cout<<--timer;  
  31. }  
  32. int find_min(int i,int j){    //找出不为-1的点所对应对角线上点数的最小值  
  33.     int count = 0,x,y;  
  34.     int x_[4] = {1,1,-1,-1},y_[4] = {1,-1,-1,1};  
  35.     for(int timer = 0;timer<4;timer++){  
  36.         x=i,y=j;  
  37.         for(;x>=0&&x<m&&y>=0&&y<n;x+=x_[timer],y+=y_[timer]){  
  38.             if(a[x][y] == 0){  
  39.                 count++;  
  40.             }  
  41.         }  
  42.     }  
  43.     return count-3;  
  44. }  
  45. void change(int i,int j){   //使对角线上的值都变为 -1  
  46.     int x_[4] = {1,1,-1,-1},y_[4] = {1,-1,-1,1},x,y;  
  47.     for(int timer = 0;timer<4;timer++){  
  48.         x=i,y=j;  
  49.         for(;x>=0&&x<m&&y>=0&&y<n;x+=x_[timer],y+=y_[timer]){  
  50.             if(a[x][y] == 0)  
  51.             a[x][y] = -1;  
  52.         }  
  53.     }  
  54.       
  55. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值