p1140【飞船控制站】

    除了A+B,应该是第一次写5星题吧QAQ,其实题并不是多难,主要是细节细节哇QAQ.........    

描述 Description
“神州十号”飞船已经圆满发射成功了,你可知道飞船的顺利运行离不开地面对其的测控吗?因而必须保证飞船运行的轨道被测控站的雷达所全部覆盖,才能正常接受和传输信号。而由于测控站所控制的范围越小,信号接收情况越好,技术难度也越低。所以我们希望在覆盖整个轨道的前提下,使得测控站所需控制的范围越小越好。由于条件限制,最多只能建立K个测控范围相同的测控站,而且并不是任何位置都可以建立测控站的,所以需要找出一种方案,使得所需测控的范围尽量小。虽然离真正的模型还有一定差距,但喜欢编程的你当然对此问题跃跃欲试了。

为了你的方便,已经帮你把地球抽象展开成一个N*2M的平面矩阵(N为奇数)。其中前M列是东半球,后M列是西半球,最中间的一行为赤道。为了简化问题,飞船的轨道可以看作是在一条穿越东西半球的经线上空(虽然实际并非如此),在此矩阵表示为第I列和第I+M列(1<=I<=M)两端对接形成的一个环。矩阵的每一个格子中可以建立一个监测站,但某些格子除外(比如其他国家的领土或是条件恶劣的地区)。假设测控半径为R,则每个测控站的控制范围可以向上向下各延伸R个格子,即总长度为2R+1的区间。测控范围的重叠并不会相互影响,并且显然有R>=0且2R+1<=N(因为地球是圆的,测控范围最多只能是一个半球)。

由于飞船有M条可选轨道,所以需要你计算出对于每条轨道,最小的测控半径是多少。注意由于控制的需要,对于任意一条轨道,在东半球的赤道上都必须建立一个测控站,并且保证在东半球的赤道上建站不会有限制。

输入格式 Input Format
输入的第一行为三个正整数N,M,K表示矩阵的大小以及测控站的数量。保证有(2<=N,M<=1000,2<=K<=2N,N为奇数)。接下来N行,每行2M个字符,如果是1则表示可以放置测控站,否则为0表示无法放置。(保证中间一行的前M个字符一定为1)

输出格式 Output Format
输出包含M行,每行包含一个正整数,第I行表示第I条轨道所需最小的测控半径R为多少(保证必然有解),轨道从左到右依次编号。

样例输入 Sample Input
5 2 4
0110
0000
1100
0011
1000

样例输出 Sample Output
1
2

注释 Hint
对于轨道1:从第一行第一列开始向下可以展开为0010101001(首尾相连)
对于轨道2:从第一行第二列开始向下可以展开为1010001000(首尾相连)
两条轨道均把可选点全部建站即可。

数据规模:
对于30%的数据,有N,M<=15
对于60%的数据,有N,M<=100
对于100%的数据,有N,M<=1000

    题值得一写,会让你更加注重细节

    思路:二分+贪心,二分肯定都会,直接二分半径。而且他还给你了东半球赤道一定会建飞船控制站,所以每次检查就是从这个赤道开始。

    但是怎么检查呢???

    既然给你了做多只能建k个飞船控制站,所以你就得是在这个半径R下建最少的飞船控制站来覆盖整个轨迹。然后就从赤道开始覆盖,在覆盖的同时

    直接记录下一个理这个控制站最远并且能覆盖到的控制站(如果你先覆盖在去查找会超时的,别问我怎么知道的)

    具体详解见程序里的标注:

      

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 using namespace std;
  7 int a[2100][2100];
  8 int b[2100];
  9 int n,m,k;
 10 bool f[2100];
 11 int la=0;
 12 int cover(int q,int x,int now)//覆盖
 13 {
 14     int id=-1;
 15     if(q==1)//向前覆盖
 16     {
 17         int sum=0;
 18         for(int i=now;;i--)
 19         {
 20             if(i<1)
 21                 i+=n*2;
 22             if(!f[i])
 23                 la++;
 24             f[i]=true;
 25             if(sum==x)
 26                 break;
 27             sum++;
 28         }
 29     }
 30     else//向后覆盖
 31     {
 32         int sum=0,wr=0;
 33         for(int i=now;;i++)
 34         {
 35             if(sum<=x)//先覆盖
 36             {
 37
 38                 if(i>n*2)
 39                     i-=n*2;
 40                 if(b[i])
 41                     id=i;
 42                 if(!f[i])
 43                     la++;//记录覆盖的次数
 44                 f[i]=true;
 45                 sum++;
 46             }
 47             else if(wr<=x)//注:因为你要查找下一个飞船控制站可以和这个飞船控制站把这两个控制站中间的所有路线覆盖住,所以再向下找一个半径x
 48             {
 49                 if(x==0)//if语句的顺序一定要注意,我就这样错了
 50                     break;
 51                 if(i>n*2)
 52                     i-=n*2;
 53                 if(b[i])
 54                     id=i;
 55                 wr++;
 56             }
 57             else
 58                 break;
 59         }
 60     }
 61     return id;
 62 }
 63 bool check(int x)
 64 {
 65     la=0;
 66     int K=0;
 67     memset(f,0,sizeof(f));
 68     int now=n/2+1;
 69     for(int i=now;;)
 70     {
 71         bool wa=false;
 72         if(i>n*2)
 73             i-=n*2;
 74         if(K==k)
 75             break;
 76         if(b[i]==1)
 77         {
 78             int j=i;
 79             K++;
 80             cover(1,x,i);//覆盖
 81             i=cover(0,x,i);//记录下一个飞船控制站并且直接跳到下一个点
 82             if(j!=i)//如果i被更新了,就是说找到下一个飞船控制站了
 83                 wa=true;
 84         }
 85         if(la==2*n)//如果此时所有的路程全被覆盖了直接退出
 86             return true;
 87         if(wa&&i==now)//如果i被更新了,并且又从新回到了赤道
 88             break;
 89         int ha=0;
 90         if(!wa)//如果i没背更新
 91             i++;
 92
 93     }
 94     return (la==n*2);
 95 }
 96 int search()//二分查找
 97 {
 98     int l=0,r=n*2+1,mid;
 99     while(l+1<r)
100     {
101         mid=(l+r)>>1;
102         if(check(mid))
103             r=mid;
104         else
105             l=mid;
106     }
107     if(check(l))
108         return l;
109     else
110         return r;
111 }
112 int main()
113 {
114     //freopen("add.out","w",stdout);
115     memset(b,-1,sizeof(b));
116     scanf("%d%d%d",&n,&m,&k);
117     char s[2100];
118     for(int i=1;i<=n;i++)
119     {
120         scanf("%s",s);
121         for(int j=1;j<=m<<1;j++)
122         {
123             char ch=s[j-1];
124             a[i][j]=ch-‘0‘;
125         }
126     }
127     for(int i=1;i<=m;i++)
128     {
129         int sum=0;
130         for(int j=1;j<=n;j++)
131             sum++,b[sum]=a[j][i];
132         for(int k=n;k>=1;k--)
133             sum++,b[sum]=a[k][i+m];
134         /*for(int r=1;r<=sum;r++)
135             cout<<b[r];
136         cout<<endl;*/
137         int ans=search();
138         cout<<ans<<endl;
139     }
140     return 0;
141 }

AC代码

时间: 2024-08-11 05:27:22

p1140【飞船控制站】的相关文章

P1140 相似基因

P1140 相似基因 题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了4种核苷酸,简记作A,C,G,T.生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物. 在一个人类基因工作组的任务中,生物学家研究的是:两个基因的相似程度.因为这个研究对疾病的治疗有着非同寻常的作用. 题目描述 两个基因的相似度的计算方法如下: 对于两个已知基因,例如AGTGATG和GTTAG,将它们的碱基互相对应.当然,中间可以加入一些空碱基-,例如: 这样,两个基因之间的相似度就可以用碱基之间相似度的

PHP7飞船来了

闹眼子?这里说的飞船不是真的飞船,是被成为飞船符号(<=>). 在PHP7,一个新的功能,飞船操作符已经被引入.它是用于比较两个表达式.当第一个表达式比第二个表达式分别小于,等于或大于它返回-1,0或1. <?php    //整型比较    print( 1 <=> 1);print("<br/>");    print( 1 <=> 2);print("<br/>");    print( 2 &

动态规划 洛谷P1140 相似基因

P1140 相似基因 题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了4种核苷酸,简记作A,C,G,T.生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物. 在一个人类基因工作组的任务中,生物学家研究的是:两个基因的相似程度.因为这个研究对疾病的治疗有着非同寻常的作用. 题目描述 两个基因的相似度的计算方法如下: 对于两个已知基因,例如AGTGATG和GTTAG,将它们的碱基互相对应.当然,中间可以加入一些空碱基-,例如: 这样,两个基因之间的相似度就可以用碱基之间相似度的

NSOJ 飞船汇合(经典)

一支分散的飞船舰队,需要汇合到主舰,但是这种飞船在太空中飞行的耗油与质量没有关系,只与发动机打开的时间有关系,为了节省油量,指挥官通知,汇合途中,多台飞船可以串成串飞行,这样只需启动一台发动机,由于安全因素飞船只能走某些航线(某飞船到某飞船的航线).指挥发现这样的移动方案可能有多种,但最短汇合时间相同,指挥官想考察你是否知道在总耗油最小的情况下,最短多久汇合完毕. Input T(T<10)组数据每组第一行有一个整数N(飞船个数<=300),之后第一行是其他飞船到主舰的时间,再有n行,每行n个

火星人乘坐核动力飞船回故乡

请看以下示意图: 这是猎户座(Orion)核动力飞船的示意图.飞船分三部分:推进模块.核燃料舱与负载舱. 一般人听说过核动力航母,没有听说有什么核动力飞船.飞船在天上快速飞驰,核动力怎么用得上?核动力飞船的工作原理其实很简单:把核燃料不断地推送到飞船的尾部,使其分成小颗粒,自动地爆炸,形成小火球,温度急剧上升至数千度,产生高速喷射的等离子流(plasma),推动飞船快速飞行. 简而言之,核动力飞船依靠微型核炸弹(Nucleurboomb)连续不断的爆炸所产生的推力前进.飞船喷射的粒子流,速度高达

E.T.的飞船

此页面为WP8"E.T.的飞船"应用的发布页面. E.T.的飞船是一款介绍古今中外关于外星人传说故事的WP8应用. 此页面主要记录开发进度.APP发布等情况. -------------------相关进度--------------------- 目前进度:UI相关资源前期准备中,各相关开放平台的AppID申请中...

小老虎飞船

今天再次严重雾霾,儿子继续在家放羊,晚上回到家妈妈告诉我他今天的表现相比昨天有所下降,虎威威的积分效果也在逐步减弱,连续两天没上幼儿园关在家里让爸妈可没少费心,都有些招架不住了,我回家的时候看他正披着披风穿着小美的靴子在家里上串下跳,寻找披风飞扬的感觉,已经洗完澡的他又是满背的汗,精力无处释放.    今天冬至,爸妈准备了饺子,只要回家吃饭,不管多晚进门总能吃到热腾腾的可口饭菜,爸妈的悉心照顾,让每天回到家都感到无比温馨.    吃饭的时候,儿子通常会坐在我的旁边,一边看我吃饭,一边陪我聊天,忍

神舟飞船上的计算机使用什么操作系统,为什么是自研发不是 Linux?

中国航天用的SpaceOS主要内容是仿造美国风河系统公司的VxWorks653(653是产品名,并非版本号). 先解释为什么用这个系统不用Linux: 航天器的内存和CPU都非常弱,弱到什么程度呢:天宫一号的CPU是10MHz的,内存是2M,这种配置跑Linux比较费劲,虽然也并非不可能但要裁剪Linux内核确实太麻烦了. 而Linux的致命缺陷就是Linux不是一个硬实时操作系统.实时操作系统(RTOS)有一系列严格的定义:包括严格按照任务优先级抢占执行,快速的中断响应,对关中断的时间有非常严

cocos2d 游戏开发:Cocos2d v3 &quot;hello world&quot;+显示飞船

V3 RC4 版本图片 显示一个飞船 将Chapter1中 SpaceCargoShip.png 文件 添加到项目里面. 代码在 init : CCSprite *spaceCargoShip = [CCSprite spriteWithImageNamed:@"SpaceCargoShip.png"]; [spaceCargoShip setPosition:ccp(200.0f,150.9f)]; [self addChild:spaceCargoShip]; 在上面的代码下增加如