20111018 模拟赛
| 题目名称 | Lyric | Trick | Maze | Dormitory |
| 可执行文件名 | Lyric | Trick | Maze | Dormitory |
| 输入文件名 | Lyric.in | Trick.in | Maze.in | Dormitory.in |
| 输出文件名 | Lyric.out | Trick.out | Maze.out | Dormitory.out |
| 时限 | 1s | 1s | 1s | 1s |
| 内存限制 | 128M | 128M | 128M | 128M |
| 测试点数目 | 10 | 10 | 10 | 10 |
| 测试点分值 | 10 | 10 | 10 | 10 |
| 题目类型 | 传统 | 传统 | 传统 | 传统 |
Lyric
【问题描述】
痛过以后 才知情已难寻
吾爱至斯 只剩飞花梦影
回首再望 蜀山依旧伫立
看尽浮沉 独饮回忆 ——《少年情》
旋律动听的曲子,伴着意境深远的lyric而显得更加优美。要想学会一首歌,没有一份装订精美的歌词,你让我情何以堪。
你的任务是,将一份歌词,按照给出规则整理好。
【输入格式】
若干行文字(包括按规定格式给出歌曲名,歌词)
每一行格式为 标识+内容
标识[name]表示后接歌曲名
标识[mm:ss]表示后接歌词,其中m,s表示每一位数字,为歌词出现的时间。保证符合正常的计时方式。
若存在时间相同的歌词,则应按规则依次首尾相连在同一行输出,规则如下:
1、 长度短的靠前;
2、 长度相同则字典序小的靠前。
【输出格式】
第一行八个空格+歌曲名
第二行及以后按时间顺序列出歌词
【输入样例】
[00:02]she is the heaven-sent angel you met
[00:05]=.=.=.=.=
[00:04]she is so pretty all over the world
[00:01]she is the one that you never forget
[name]she
[00:03]oh,she must be the reason why God made a girl
【输出样例】
she
she is the one that you never forget
she is the heaven-sent angel you met
oh,she must be the reason why God made a girl
she is so pretty all over the world
=.=.=.=.=
【数据hint】
1、 保证歌曲名和歌词均为英文字母,字符。
2、 保证每一行不超过256个字符
3、 保证输入不超过2000行
//用字符串模拟恶心人//C处理字符串的空格太麻烦了,还是写Pprogram lyric;typenode=recordtime,len:longint;s:ansistring;end;vara:array[0..2100] of node;i,last,n,p,tt,mm:longint;s,m,t:ansistring;procedure swap(var a,b:node);varc:node;beginc:=a;a:=b;b:=c;end;function cmp(a,b:node):boolean;beginif (a.time<b.time) then exit(true)else if (a.time>b.time) then exit(false)else if (a.len<b.len) then exit(true)else if (a.len>b.len) then exit(false)else if (a.s<b.s) then exit(true);exit(false);end;procedure sort(l,r:longint);vari,j:longint;x:node;begini:=l;j:=r;x:=a[(l+r) shr 1];repeatwhile (cmp(a[i],x)) do inc(i);while (cmp(x,a[j])) do dec(j);if (i<=j) thenbeginswap(a[i],a[j]);inc(i);dec(j);end;until i>j;if (i<r) then sort(i,r);if (l<j) then sort(l,j);end;beginassign(input,'lyric.in');reset(input);assign(output,'lyric.out');rewrite(output);while (not eof) dobegininc(n);readln(s);p:=pos(']',s);a[n].s:=copy(s,p+1,length(s)-p);a[n].len:=length(a[n].s);if (s[2]='n')and(s[3]='a')and(s[4]='m')and(s[5]='e') thenbegina[n].time:=-1;endelsebegin//m:=copy(s,2,pos(':',s)-2);m:='';m:=m+s[2]+s[3];val(m,mm);t:='';t:=t+s[5]+s[6];//t:=copy(s,pos(':',s)+1,p-pos(':',s)-1);val(t,tt);a[n].time:=mm*100+tt;end;end;sort(1,n);write(' ',a[1].s);last:=-1;for i:=2 to n dobeginif (a[i].time<>last) thenbeginwriteln;end;write(a[i].s);last:=a[i].time;end;writeln;close(input);close(output);end.
Trick
【题目描述】
暴躁的稻草人,最终以自爆来给我们的队伍致命一击,全队血量见底,稻草人也一分为二。还好我们有雨柔妹子,瞬间精力回满。不过事后姜小弟和龙腹黑就开始了报复。
他们读取存档,将若干暴躁的稻草人活捉。然后将它们放到一个迷宫的入口。迷宫是有向图。此刻暴躁的稻草人们在1号位置,而迷宫出口在n号位置。因为稻草人会自爆,所以他每经过一条路数量就会加倍。每条路上有敌人,会消耗稻草人c[i](c[i]为负值);当然有些时候路上也会遇到止血草之类的东西,这时候就可以补充一些稻草人咯(c[i]为正值)。如果小稻草人死光了,那么稻草人也就可以看做是挂了。希望你帮助稻姜龙二人算出用最少的初始稻草人使其能够走出迷宫。
【输入格式】
第一行两个数N(<=50000),M(<=100000)表示点位数与边数。
以下M行,每行三个数a,b,c表示从a到b两点间的边权是c(|c|<=10000)
【输出格式】
输出仅一个整数,表示最小初始稻草人数。
【输入样例】
5 4
1 2 -3
1 3 -6
3 4 1
4 5 -9
【输出样例】
4
//应该还有一种方法是只做一边SPFA,没想清,还是写个二分吧program trick;typeedge=recordx,w,next:longint;end;vare:array[0..200000] of edge;k:array[0..50000] of longint;d:array[0..50000] of longint;v:array[0..50000] of boolean;f:array[0..1000000] of longint;n,m,i,j,tot,a,b,c:longint;l,r,mid:longint;flag:boolean;procedure add(a,b,c:longint);begininc(tot);e[tot].x:=b;e[tot].w:=c;e[tot].next:=k[a];k[a]:=tot;end;function check(s:longint):boolean;vari,x,t,head,tail,cnt:longint;beginfor i:=1 to n dobegind[i]:=-1;v[i]:=false;end;cnt:=0;d[1]:=s;v[1]:=true;head:=0;tail:=1;f[tail]:=1;while (head<tail) dobegininc(head);x:=f[head];v[x]:=false;t:=k[x];if (d[x]<=0) then continue;while (t<>0) dobeginif (d[e[t].x]=-1) or (d[e[t].x]<d[x]*2+e[t].w) thenbegind[e[t].x]:=d[x]*2+e[t].w;if (not v[e[t].x]) thenbeginv[e[t].x]:=true;inc(tail);f[tail]:=e[t].x;end;end;t:=e[t].next;end;end;if (d[n]>0) then exit(true) else exit(false);end;beginassign(input,'trick.in');reset(input);assign(output,'trick.out');rewrite(output);readln(n,m);for i:=1 to m dobeginreadln(a,b,c);add(a,b,c);end;l:=0;r:=200000;while (l<r) dobeginmid:=(l+r) shr 1;flag:=check(mid);if not flag then l:=mid+1 else r:=mid;end;writeln(l);close(input);close(output);end.
Maze
【题目描述】
众所周知(怎么又是众所周知),仙剑的迷宫是难走的要命,某人就在仙四的女罗岩困了很长时间。
我们可以把女罗岩的地图抽象成n*n的地图,我们现在在(1,1)处,而出口在(n,n)。每次行动只能向上下左右移动一格。图中有M个机关,只有打开某个机关之后,与该机关相对应的地方才可以行走。当然,地图中还会有小怪兽,他们能够监视着他所在地区以及上下左右共五个方格,我们不愿意与他们战斗(为了节省时间),所以他们能监视到的地方不可以行走。同样的,地图上的障碍物处也不能经过。
我们需要求出从起点到终点的最少步数。
【输入格式】
第1行,两个整数N, M。表示地图大小为N*N,机关的数量为M。
第2-N+1行,每行N个整数,每个整数i可能是0,-1,-2或者一个正整数。i=0表示该位置为一块空地,i=-1表示该位置为一个障碍物,i=-2表示该位置为一个小怪兽。如果i是一个属于[1,M]的正整数,则表示该位置为一个机关,其编号为i。如果i是一个大于M的正整数,则表示该位置为一个机关控制区域,它由编号为i-M的机关控制。
【输出格式】
一个整数,为走出迷宫所需的最少的步数。
【输入样例】
6 2
0 0 0 -2 -1 2
-1 0 0 0 -1 0
-2 0 0 0 3 3
-2 0 0 -1 -1 4
0 -1 0 0 -1 0
1 0 0 0 -1 0
【输出样例】
24
【样例说明】
地图如下图,S为入口,T为目标,黑色的单元格为障碍物。每个E表示一个小怪兽,(E)为小怪兽的监视范围。K1表示机关1,K2表示机关2。D1表示机关为1的控制区域,D2表示机关为2的控制区域。
最优的路线为(1,1) →(1,2) →(2,2) →(2,3) →(3,3) →(4,3) →(5,3) →(6,3) →(6,2) →(6,1)(破坏供电1) →(6,2) →(6,3) →(5,3) →(4,3) →(3,3) →(3,4) →(3,5) →(3,6) →(2,6) →(1,6)(破坏供电2) →(2,6) →(3,6) →(4.6) →(5,6) →(6,6)
【数据规模】
1<=N<=50
0<=M<=16
//二进制+BFS飘过
#include<cstdio>
#include<cstring>
#include<cstdlib>
int di[5]={0,0,1,0,-1};
int dj[5]={0,1,0,-1,0};
int k[17]={0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};
int n,m;
int a[52][52];
struct node{
int x,y,n,key;
}f[1000000];
bool v[65537][52][52];
int main(){
freopen("maze.in","r",stdin);
freopen("maze.out","w",stdout);
scanf("%d%d",&n,&m);
int t;
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
scanf("%d",&t);
if (a[i][j]!=-1) a[i][j]=t;
if (t==-2){
if (j>1) a[i][j-1]=-1;
if (j<n) a[i][j+1]=-1;
if (i>1) a[i-1][j]=-1;
if (i<n) a[i+1][j]=-1;
}
}
scanf("\n");
}
int head=0,tail=1,x,y;
f[1].x=1;
f[1].y=1;
v[0][1][1]=true;
while (head<tail){
head++;
for (int i=1;i<=4;i++){
x=f[head].x+di[i];
y=f[head].y+dj[i];
t=f[head].key;
if (x>0&&y>0&&x<=n&&y<=n&&!v[t][x][y]){
if (x==n&&y==n){
printf("%d\n",f[head].n+1);
return 0;
}
if (a[x][y]==-1||a[x][y]==-2) continue;
if (a[x][y]==0){
v[t][x][y]=true;
f[++tail].x=x;
f[tail].y=y;
f[tail].n=f[head].n+1;
f[tail].key=f[head].key;
continue;
}
if (a[x][y]>m){
if ((f[head].key & k[a[x][y]-m])==k[a[x][y]-m]){
v[t][x][y]=true;
f[++tail].x=x;
f[tail].y=y;
f[tail].n=f[head].n+1;
f[tail].key=f[head].key;
continue;
}
}
if (a[x][y]<=m&&a[x][y]>0){
v[t][x][y]=true;
f[++tail].x=x;
f[tail].y=y;
f[tail].n=f[head].n+1;
f[tail].key=f[head].key | k[a[x][y]];
v[f[tail].key][x][y]=true;
}
}
}
}
return 0;
}
Dormitory
【题目描述】
小蛮妹子有许多的,什么棉花糖啦,蜥蜴啊,小乌龟啊,只有你想不到的没有她没有的。
小蛮妹子的小宠物都住在一个漂亮的大屋子里,每个人都有自己的床位,但是由于小蛮妹子的宠物太多了,以至于这些宠物之间并不是都互相认识。
这些宠物们也有自己的朋友,这些朋友一直羡慕他们住的漂亮大屋子,于是有一天,小蛮妹子出去玩了,一些小宠物也偷偷出去玩了,那些留守的小宠物们开始招待来访的客人。
这些来客都打算在这里住一晚上,可是安排床位就出了麻烦。每个小宠物都只愿意在自己的直接朋友或自己的床上(如果它是小蛮的宠物)睡觉,且一物睡一张床。
询问是否能有一个方案来满足所有在留宿的宠物都能住宿。
【输入格式】
第一行一个数 T 表示数据组数。
接下来 T 组数据。
每组数据第一行一个数 n 表示涉及到的总宠物数(包括小蛮的宠物和来客)。
接下来一行 n 个数,第 i 个数表示第 i 个个宠物是否是在小蛮的宠物 (0 表示不是,1 表示是)。再接下来一行 n 个数,第 i 个数表示第 i 个人是否出去玩(0 表示不出去,1 表示出去)注意如果第 i 个人不是小蛮的宠物,那么这个位置上的数是一个随机的数,你应该在读入以后忽略它)。
接下来 n 行,每行 n 个数,第 i 行第 j 个数表示 i 和 j 是否认识 (1 表示认识,0 表示不认识,第 i 行 i 个的值为 0,但是显然自己还是可以睡自己的床),认识的关系是
相互的。
【输出格式】
每一行对应每组数据
若存在方案满足条件 输出 ^.^ ,否则输出 T.T (只有三个字符,没有空格等其他内容)
【输入样例】
1
3
1 1 0
0 1 0
0 1 1
1 0 0
1 0 0
【输出样例】
^.^
【数据hint】
对于 30% 的数据满足 1 ≤ n ≤ 12。
对于 100% 的数据满足 1 ≤ n ≤ 50,1 ≤ T ≤ 20。
//或是个二分图最大匹配吧
#include <cstdio>
#include <cstring>
int T;
int n;
int tot;
int map[60][60];
int list[60];
bool out[60];
int match[60];
bool use[60];
bool dfs(int x){
for (int i=1;i<=n;i++){
if (list[i] && map[x][i] && !use[i]){
use[i]=true;
if (match[i]==0 || dfs(match[i])){
match[i]=x;
return true;
}
}
}
return false;
}
int main(){
freopen("dormitory.in","r",stdin);
freopen("dormitory.out","w",stdout);
scanf("%d",&T);
while (T--){
memset(list,0,sizeof(list));
memset(out,0,sizeof(out));
memset(map,0,sizeof(map));
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%d",&list[i]);
}
tot=n;
for (int i=1;i<=n;i++){
int x;
scanf("%d",&x);
if (list[i] && x==1){
out[i]=true;
tot--;
}
}
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
scanf("%d",&map[i][j]);
}
scanf("\n");
}
for (int i=1;i<=n;i++)
if (list[i]==1) map[i][i]=1;else map[i][i]=0;
memset(match,0,sizeof(match));
int ans=0;
for (int i=1;i<=n;i++){
if (!out[i]){
memset(use,0,sizeof(use));
if (dfs(i)) ans++;
}
}
if (ans==tot) puts("^.^");else puts("T.T");
}
return 0;
}

浙公网安备 33010602011771号