【问题描述】

我们假设射击的目标是一个由R*C(2≤R≤C≤ 1000)个小方格组成的矩形网格。网格中每一列恰有2个白色的小方格和R-2个黑色的小方格。定义网格的行从顶至底编号为1~R,列从左至右编号为1~C。 射击者可射击C次。在连续的C次射击中,若每列恰好有一个白色的方格被射中,且不存在无白色方格被射中的行,这样的射击才是正确的。现给出N组数据,对于每组数据,如果存在正确的射击方法,则要求找到它,若不存在,输出NO。

【样例输入】

2
    4 4

2 4

3 4

1 3

1 4

5 5

1 5

2 4

3 4

2 4

2 3

【样例输出】

2 3 1 4

NO

【解题思路】

本题为1997年CEOI最后一题,解题的思路主要在于贪心策略与贪心的证明。

贪心策略:

1、统计所有行包含的白格数。

2、从还没有射击格的行中选出一个白格数最少的。

3、检查所选的行 (1)若所选行的白格数为0,则输出无解; (2)否则从所选行的白格中任选一个作为射击格,并将与该格同列的另一 个白格所处行的白格数减1。

4、返回到第2步,直到所有的行都有射击格。

5、若还有列没有选射击格,则在该列任选一白格作为射击格即可。

贪心证明:

用h[i]表示第i行的白格数。如果最开始的时候: ①min{h[i]}=0:第i行已经没有办法找到可作为射击格的白格,那么问题只能无解。        ②min{h[i]}=1:那么第i行的这一个白格必须要作为射击格,否则将因第i行没有射击格而造成问题无解。

③min{h[i]}≥2:那么在这一 行任选一个白格,顶多只会造成剩余行中有一行h值为1,再处理那一行,最多也只会再造成剩余行中有一行h   值为1,如此往复,将保持h值为1的行数不超过1行,最后最坏的情况也是造成最后一行的h值为1,继续下去所有行就都已选取了射击格了。因此,如果原问题有解,该贪心方法一定能找到一种正确的方案。由此可以证明,此贪心方法是正确的。确定贪心标准。

【代码实现】

 var a:array[..] of longint;
b:array[..,..] of boolean;
fr,fc:array[..] of boolean;
ans:array[..] of longint;
n,i,j,r,c,x1,x2,k,pos,min,code,q:longint;
flag:boolean;
begin
readln(code);
for q:= to code do
begin
fillchar(fr,sizeof(fr),false);
fillchar(fc,sizeof(fc),false);
fillchar(a,sizeof(a),);
fillchar(b,sizeof(b),);//注意初始化,没初始化WA几次……
readln(r,c);
for i:= to c do
begin
readln(x1,x2);
b[x1,i]:=true;b[x2,i]:=true;
inc(a[x1]);inc(a[x2]);
end;
repeat
min:=maxlongint;
flag:=true;
for i:= to r do
if not(fr[i]) then
break;
if not(fr[i]) then
flag:=false;
if flag then break;
for i:= to r do
if (a[i]<min)and(not(fr[i])) then
begin
min:=a[i];
pos:=i;
end;
if a[pos]= then
begin
writeln('NO');
break;
end;
fr[pos]:=true;
for j:= to c do
if (b[pos,j])and(not(fc[j])) then
begin
ans[j]:=pos;fc[j]:=true;
for k:= to r do
if (b[k,j])and(k<>pos) then
dec(a[k]);
break;
end;
until flag;
if a[pos]= then
continue;
for i:= to c do
if ans[i]= then
for j:= to r do
if b[j,i] then
begin
ans[i]:=j;
break;
end;
write(ans[]);
for i:= to c do
write(' ',ans[i]);
writeln;
end;
end.

射击比赛 (POJ 1719) 题解的更多相关文章

  1. PAT 1082. 射击比赛 (20)

    本题目给出的射击比赛的规则非常简单,谁打的弹洞距离靶心最近,谁就是冠军:谁差得最远,谁就是菜鸟.本题给出一系列弹洞的平面坐标(x,y),请你编写程序找出冠军和菜鸟.我们假设靶心在原点(0,0). 输入 ...

  2. PAT 1082 射击比赛

    https://pintia.cn/problem-sets/994805260223102976/problems/994805260990660608 本题目给出的射击比赛的规则非常简单,谁打的弹 ...

  3. POJ 1719 Shooting Contest(二分图匹配)

    POJ 1719 Shooting Contest id=1719" target="_blank" style="">题目链接 题意:给定一个 ...

  4. PAT 1082 射击比赛(20)(代码+思路)

    1082 射击比赛(20 分) 本题目给出的射击比赛的规则非常简单,谁打的弹洞距离靶心最近,谁就是冠军:谁差得最远,谁就是菜鸟.本题给出一系列弹洞的平面坐标(x,y),请你编写程序找出冠军和菜鸟.我们 ...

  5. PAT(B) 1082 射击比赛(Java)

    题目链接:1082 射击比赛 (20 point(s)) 题目描述 本题目给出的射击比赛的规则非常简单,谁打的弹洞距离靶心最近,谁就是冠军:谁差得最远,谁就是菜鸟.本题给出一系列弹洞的平面坐标(x,y ...

  6. PAT Basic 1082 射击比赛 (20 分)

    本题目给出的射击比赛的规则非常简单,谁打的弹洞距离靶心最近,谁就是冠军:谁差得最远,谁就是菜鸟.本题给出一系列弹洞的平面坐标(x,y),请你编写程序找出冠军和菜鸟.我们假设靶心在原点(0,0). 输入 ...

  7. 1082 射击比赛 (20 分)C语言

    本题目给出的射击比赛的规则非常简单,谁打的弹洞距离靶心最近,谁就是冠军:谁差得最远,谁就是菜鸟.本题给出一系列弹洞的平面坐标(x,y),请你编写程序找出冠军和菜鸟.我们假设靶心在原点(0,0). 输入 ...

  8. PAT (Basic Level) Practice (中文)1082 射击比赛 (20 分)

    本题目给出的射击比赛的规则非常简单,谁打的弹洞距离靶心最近,谁就是冠军:谁差得最远,谁就是菜鸟.本题给出一系列弹洞的平面坐标(x,y),请你编写程序找出冠军和菜鸟.我们假设靶心在原点(0,0). 输入 ...

  9. P1082 射击比赛

    P1082 射击比赛 转跳点:

  10. PAT乙级:1082 射击比赛 (20分)

    PAT乙级:1082 射击比赛 (20分) 题干 本题目给出的射击比赛的规则非常简单,谁打的弹洞距离靶心最近,谁就是冠军:谁差得最远,谁就是菜鸟.本题给出一系列弹洞的平面坐标(x,y),请你编写程序找 ...

随机推荐

  1. ELK+redis集群搭建

    ELK版本: logstash-1.4.2 kibana-4.0.3 redis-3.0.0 elasticsearch-1.4.4(最低版本) 分别启动命令: redis-server redis. ...

  2. 通过反射获取父类中的泛型参数对应的Class对象

    假设有两个类:Dao 和 PersonDao,它们的代码如下: Dao: public class Dao<T> { private Class<T> clazz; T get ...

  3. MFC学习 MFCActiveX控件

    例子包含 1. 重绘activex控件显示区域 在activex的ctrl类中ondraw中实现 2.添加修改activex控件属性(前景色, 背景色, 自定义属性),, 只要在类视图中展开libra ...

  4. Class attributes

    In order to print Card objects in a way that people can easily read, we need a mapping from the inte ...

  5. number对象,bom对象

    number对象 新创建一个number的对象,toFixed是精确到位数 var num =new Number('123.1231'); console.log(num.toFixed(1)); ...

  6. Duilib学习笔记《05》— 消息响应处理

    在Duilib学习笔记<04>中已经知道了如何将窗体显示出来,而如何处理窗体上的事件.消息呢? 一. 系统消息 窗体显示的时候我们就已经说了,窗体是继承CWindowWnd类的,对于窗体的 ...

  7. openstack4j

    Identity // V2 authentication OSClientV2 os = OSFactory.builderV2() .endpoint("http://127.0.0.1 ...

  8. docker1.12在cento7里的跨多主机容器网络

    docker1.12在cento7里的跨多主机容器网络

  9. 新写的c++日志库:log4K

    网是开源的c/c++日志库也不少,但用起来总觉得不方便,于是动手写了一个C++日志框架Log4K. 测试代码: #include "log4k.h" #pragma comment ...

  10. Groovy轻松入门——通过与Java的比较,迅速掌握Groovy (更新于2008.10.18)

    摘自: http://www.blogjava.net/BlueSUN/archive/2007/03/10/103014.html Groovy轻松入门--通过与Java的比较,迅速掌握Groovy ...