莞中松山湖长沙一中三校联考试题.docx

上传人:b****0 文档编号:12571616 上传时间:2023-04-20 格式:DOCX 页数:12 大小:19.30KB
下载 相关 举报
莞中松山湖长沙一中三校联考试题.docx_第1页
第1页 / 共12页
莞中松山湖长沙一中三校联考试题.docx_第2页
第2页 / 共12页
莞中松山湖长沙一中三校联考试题.docx_第3页
第3页 / 共12页
莞中松山湖长沙一中三校联考试题.docx_第4页
第4页 / 共12页
莞中松山湖长沙一中三校联考试题.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

莞中松山湖长沙一中三校联考试题.docx

《莞中松山湖长沙一中三校联考试题.docx》由会员分享,可在线阅读,更多相关《莞中松山湖长沙一中三校联考试题.docx(12页珍藏版)》请在冰豆网上搜索。

莞中松山湖长沙一中三校联考试题.docx

莞中松山湖长沙一中三校联考试题

莞中-松山湖-长沙一中三校联考试题

SubRaY被布置了n道作业题,可是他一道也不会..但他知道有w位高手,并知道每位高手会做哪些题,请问SubRaY至少请多少位高手,才能把所有的题都做出来?

[输入][solve.in]

第一行两个整数n,w表示有n道作业题和w位高手,作业题以1..n编号.接下来w行,第i+1行第一个数li表示第i位高手会做的题目的数量,接下来li个数表示第i位高手会做哪些题目.

[输出][solve.out]一个数,SubRaY至少要请多少位高手.

[样例输入]

44

212

14

3234

213

[样例输出]

2

[数据范围]

对于40%的数据,3<=n,w<=10,

对于100%的数据,3<=n,w<=60,1<=li<=6

 

解法:

搜索题,本来打算n只开到10作为一道送分题的(这也是为什么这道题是第一题的原因),但是鉴于如果真这么做实在太水(掉RP),所以改为设4个送分点….

搜索是基础算法.虽然近几年中NOIP搜索题占的比率并不大,但是在考试临近结束时,或者有题不会时,写一个简单的搜索程序往往会带来意想不到的结果.比如2006年的金明的预算方案,有很多大牛虽然写了DP但是某一个小细节处理错了,0分;那些写搜索的反而至少能得40-50分,加几条剪枝甚至能达到80-90分.可见搜索在实战中的作用.

这道题并不难,只需加几条剪枝就可全过:

1可行性剪枝,如果当前选择的高手的数量已经大于等于当前最优解的数量,剪.这也是最基础,最简单,但却是最实用的剪枝之一.

2重复数据数据中不可避免地会出现某一个高手会做的题目,有另外一个高手全会做的情况.这种情况下,这个高手就不需要了,因为它完全可以被另外那个高手取代.

3仅有情况有的题只能被一位高手解决,所以在搜索之前把这位高手会做的题目删去吧,最优解中一定包含这位高手,所以这些题一定能被解决.

其实这道题模型就是2011年东莞特长生考试最后一题。

程序:

vari,j,k,n,m,ans,max,x:

longint;

a:

array[1..60,1..6]oflongint;

b:

array[1..60,1..60]ofboolean;

l,d:

array[1..61]oflongint;

s:

array[1..60,0..60]oflongint;

can:

boolean;

proceduredfs(v,x:

longint);

vari,j,k:

longint;

begin

while(d[x]>0)and(x<=n)doinc(x);

ifx>nthenbegin

ifmax>vthenmax:

=v;

exit;

end;

ifv>=max-1thenexit;

fork:

=1tos[x,0]dobegin

i:

=s[x,k];

forj:

=1tol[i]doinc(d[a[i,j]]);

dfs(v+1,x+1);

forj:

=1tol[i]dodec(d[a[i,j]]);

end;

end;

begin

{assign(input,'solve.in');reset(input);

assign(output,'solve.out');rewrite(output);}

readln(n,m);

fori:

=1tomdobegin

read(l[i]);

forj:

=1tol[i]dobegin

read(a[i,j]);b[i,a[i,j]]:

=true;

end;

readln;

end;

fori:

=1tomdo

forj:

=1tomdo

if(i<>j)and(l[i]>0)and(l[j]>0)thenbegin

can:

=true;

fork:

=1tol[i]doifnotb[j,a[i,k]]thenbegin

can:

=false;break;

end;

ifcanthenbegin

l[i]:

=0;break;

end;

end;

ans:

=0;

fori:

=1tondobegin

forj:

=1tomdoifb[j,i]thenbegin

inc(s[i,0]);s[i,s[i,0]]:

=j;

end;

ifs[i,0]=1thenifl[s[i,1]]<>0thenbegin

x:

=s[i,1];ans:

=ans+1;

forj:

=1tol[x]doinc(d[a[x,j]]);

l[x]:

=0;

end;

end;

max:

=9999;

dfs(ans,1);

writeln(max);

{close(input);close(output);}

end.

 

2.迷宫

问题描述:

小希非常喜欢玩迷宫游戏,现在她自己设计了一个迷宫游戏。

在她设计的迷宫中,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走了回头路)。

小希现在把她的设计图给你,让你帮忙判断她的设计图是否符合她的设计思路。

比如下面的例子,前两个是符合条件的,但是最后一个却有两种方法从5到达8。

数据输入:

输入包含多组数据,每组数据是一个以00结尾的整数对列表,表示了一条通道连接的两个房间的编号。

房间的编号至少为1,且不超过100000。

每两组数据之间有一个空行。

整个文件以两个-1结尾。

数据输出:

对于输入的每一组数据,输出仅包括一行。

如果该迷宫符合小希的思路,那么输出"1",否则输出"0"。

输入输出样例:

Migong.in

68535264

5600

8173628975

74787600

386864

53565200

-1-1

Migong.out

1

1

0

解法:

这道题实际是一道数据结构题,NOIP的数据结构也是很重要的考察内容,比如线性表、哈希表、并查集、树状数组等。

这道题很裸的要求判定图中任意两点是否存在唯一通路,对于具有唯一通路的图而言实际上就是树结构。

根据树的特征可以知道n个节点的树,其必然有只有n-1条边相连,对数据进行初步判断将输入边数不等于节点数n-1的图去掉,剩下来的就是判断图中是否存在回路,如果有回路则必然导致有节点不在一个连通图中,所以实际就是判断图的连通性。

图的连通性判断由很多方法,比如深搜或广搜,比如种子填充算法BloodFill,比如最小生成树算法,当然更高效的还有并查集算法,

下面就是使用并查集解决的参考代码,这道题特别要注意的地方是空集也是可行的!

程序:

programmigong;

vari,j,a,b,max,min,tt,tr,tx,x,y:

longint;

fa,rank:

array[1..100001]oflongint;

map:

array[1..100000]ofboolean;

functionmaxx(x,y:

longint):

longint;

begin

ifx>ythenexit(x);

exit(y);

end;

functionminn(x,y:

longint):

longint;

begin

ifx>ythenexit(y);

exit(x);

end;

functionfind(x:

longint):

longint;

begin

ifx<>fa[x]thenfa[x]:

=find(fa[x]);

find:

=fa[x];

end;

procedureunion(x,y:

longint);

begin

x:

=find(x);

y:

=find(y);

ifrank[x]

=y

elsebegin

ifrank[x]=rank[y]theninc(rank[x]);

fa[y]:

=x;

end;

end;

begin

read(a,b);

while(a<>-1)dobegin

fori:

=1to100dofa[i]:

=i;

fillchar(rank,sizeof(rank),0);

fillchar(map,sizeof(map),false);

tr:

=0;tt:

=0;tx:

=0;

min:

=100001;max:

=-1;

while(a<>0)dobegin

inc(tt);{边数}

map[a]:

=true;map[b]:

=true;

max:

=maxx(max,maxx(a,b));

min:

=minn(min,minn(a,b));

union(a,b);

read(a,b);

end;

fori:

=mintomaxdoifmap[i]=truethenbegin

iffa[i]=itheninc(tr);{根节点数目,节点都在一棵树上}

inc(tx);{点的个数}

end;

if((tx-1=tt)and(tr=1))or((max=-1)and(min=100001))thenwriteln

(1)

{利用树的特性}{树为空时,结果为1}

elsewriteln(0);

read(a,b);

end;

end.

3.牛棚安排

【问题描述】

FarmerJohn的N(1<=N<=1000)头奶牛分别居住在农场所拥有的B(1<=B<=20)个牛棚的某一个里。

有些奶牛很喜欢她们当前住的牛棚,而另一些则讨厌再在它们现在所在的牛棚呆下去。

FJ在忍受了若干次奶牛的抱怨后,决定为所有奶牛重新安排牛棚,使最不满的那头奶牛与最高兴的奶牛的心情差异最小,即使这会让所有奶牛都更加郁闷。

每头奶牛都把她对各个牛棚的好感度从高到低排序后告诉了FJ。

当然,如果一头奶牛被安排到的牛棚在她给出的列表中越靠后,她就会越郁闷。

你可以认为奶牛的郁闷指数是她被分配到的牛棚在列表中的位置。

奶牛们是斤斤计较的,她们无法容忍别的奶牛在自己喜欢的牛棚里快乐地生活,而自己却呆在一个自己不喜欢的牛棚里。

每个牛棚都只能容纳一定数量的奶牛。

FJ希望在每个牛棚都没有超出容量限制的前提下,使最郁闷和最高兴的奶牛的郁闷指数的跨度最小。

FJ请你帮他写个程序,来计算这个最小的郁闷指数跨度到底是多少。

【输入】

第1行:

包含2个用空格隔开的整数N和B,分别表示牛和牛棚的数量

第2..N+1行:

每行包含B个用空格隔开的整数,刚好完全包含1..B的整数。

第i+1行的第一个整数,表示奶牛i最喜欢的牛棚编号。

第二个整数表示奶牛i的列表中排在第二位,也就是她第二喜欢的牛棚。

依此类推。

第N+2行:

包含B个用空格隔开的整数,第i个整数表示牛棚i最多能容纳的奶牛的数目。

所有牛棚能容纳奶牛头数的和至少是N。

【输出】

第1行:

输出一个整数,表示所有奶牛中最高兴与最郁闷的牛的郁闷指数跨度

【输入输出样例】

stead.in

stead.out

64

1234

2314

4231

3124

1342

1423

2132

2

【样例说明】

每头奶牛都能被安排进她的第一或第二喜欢的牛棚。

下面给出一种合理的分配方案:

奶牛1和奶牛5住入牛棚1,牛棚2由奶牛2独占,奶牛4住进牛棚3,剩下的奶牛3和奶牛6安排到牛棚4。

解法:

原题模型是二分图匹配的,当然也可以用网络流来解,这里考察的是noip的算法用的是动态规划

varn,m,l,r,ans,i,j:

longint;

a:

array[0..1100,0..30]oflongint;

p:

array[0..30,0..1100]oflongint;

tot:

array[0..30]oflongint;

u:

array[0..30]ofboolean;

functionpd(k:

longint):

boolean;{多重二分匹配图}

vari,jm,j:

longint;

begin

fori:

=ltordobegin

jm:

=a[k,i];

ifp[jm,0]

inc(p[jm,0]);p[jm,p[jm,0]]:

=k;

exit(true);

end

elseifnotu[jm]thenbegin

u[jm]:

=true;

forj:

=1top[jm,0]doifpd(p[jm,j])thenbegin

p[jm,j]:

=k;

exit(true);

end;

end;

end;

exit(false);

end;

begin

readln(n,m);

fori:

=1tondobegin

forj:

=1tomdoread(a[i,j]);

readln;

end;

fori:

=1tomdoread(tot[i]);

readln;

ans:

=maxlongint;

forl:

=1tomdobegin{最大高兴指数}

fillchar(p,sizeof(p),0);

r:

=l;

fori:

=1tondobegin{枚举第i头牛}

whiletruedobegin

fillchar(u,sizeof(u),0);

ifpd(i)thenbreak;

inc(r);{最小高兴指数}

ifr>mthenbreak;{全部牛棚都找过}

ifr-l+1>=ansthenbreak;{剪枝}

end;

ifr>mthenbreak;

ifr-l+1>=ansthenbreak;

end;

ifr>mthenbreak;

if(r<=m)and(r-l+1

=r-l+1;

end;

writeln(ans);

end.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 城乡园林规划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1