Day1
题目名称 | math | chemistry | physics |
输入文件 | math.in | chemistry.in | physics.in |
输出文件 | math.out | chemistry.out | physics.out |
测试点数目 | 10 | 10 | 5 |
测试点分数 | 10 | 10 | 20 |
题目类型 | 传统 | 传统 | 传统 |
时间限制 | 1s | 1S | 1S |
空间限制 | 128MB | 128MB | 128MB |
1、函数 又是函数
问题描述
话说leve最最最讨厌数学,每次考试都因为数学悲剧…….
大头头还极其可恶的冒天下之大不韪的让同学们把那本16开500页的2012高考数学核按钮做完(为什么要叫核按钮呢?你懂得)…….
现在,leve被一道函数题难住了,为了省出更多的时间学oi,她把这道题交给了你。
给定一个函数f(x),它的定义域为1~n,值域为1~m,为了简化题目,现在将每个x对应的f(x)都告诉你。现在,你的任务就是求出一段最小的连续的区间,使得这段区间内x对应的f(x)可以取遍1~m之间的数,输出这段区间的长度。
输入文件
共两行,第一行两个数n,m。
第二行n个数第i个数是i对应的函数值。每两个数中间有一个空格隔开,结尾无空格。
输出文件
一个数,要求的区间长度。数据保证有解。
样例输入
7 6
6 1 2 4 4 5 3
样例输出
7
数据范围
n<=1000000 m<=n
#include <cstdio> #include <algorithm> #define INF 20000000 using namespace std; int n,m; int ans=INF; int a[2000000]; int cnt[2000000]; int main(){ freopen("math.in","r",stdin); freopen("math.out","w",stdout); scanf("%d%d",&n,&m); for (int i=1;i<=n;i++){ scanf("%d",&a[i]); } int head=1,tot=0; for (int i=1;i<=n;i++){ if (cnt[a[i]]==0) tot++; cnt[a[i]]++; while (cnt[a[head]]>1){ --cnt[a[head]]; ++head; } if (tot==m){ if (ans>i-head+1) ans=i-head+1; } } printf("%d\n",ans); return 0; }
2、化学老师的难题(chemistry)
问题描述
话说这天是化学课,loongint同学正在专注的写着数学学案,耳中回响着动听的“清养羹”、“炭涮羹”,说时迟那时快,化学老师突然来到它的身边,温柔的说:“尤龙童鞋,请你给大家说一下这个数学学案和化学课的关系吧”,loongint童鞋果断没有鸟他,于是,化学老师就发表了那个无比经典的言论“不要以为我是男老师,你们就可以欺负我!”
接着,化学老师邪恶的说道:“既然你这么喜欢素学,我就给你粗个素学题吧。现在我的手里有n只试管,每个试管有一定的体积vi,我要量出q体积的液体,你说我最少要用几支试管,并且告诉我一个字典序最小的方案”。(如果你有一个1体积的试管,就可以量出任意体积的液体)。
这可难坏了loongint,为了不再某女生面前丢脸,他请你帮他一把。
输入文件
第一行,一个整数q
第二行,一个整数p,表示试管的数量
第三~p+2行,每行一个整数,表示每个试管的体积vi
输出文件
第一行,一个整数m,表示最少需要的试管数
第二行,m个空格分隔开的整数,表示符合条件的一个字典序最小的方案,要求从小到大排序。
样例输入
16
3
3
5
7
样例输出
2 3 5
数据范围
1<=q<=20,000
1<=p<=100
1<=vi<=10000
type arr=array[0..20000]of integer; var p,q,maxd,i,j,k,l,m,n:longint; v:array[0..100]of longint; f:arr; t:array[0..100]of longint; flag:boolean; procedure dfs(nowd:longint); var newmax,i,j:longint; tmp:arr; procedure make(x:longint); var i:longint; begin for i:=0 to q-x do if (f[i]<>-1)and(i+x<=q) then inc(f[i+x]); end; begin if nowd>maxd then begin if f[q]>=0 then flag:=true; exit; end; tmp:=f; for i:=t[nowd-1]+1 to p do begin t[nowd]:=i; make(v[i]); dfs(nowd+1); if flag then exit; f:=tmp; end; end; function check:boolean; begin flag:=false; dfs(1); check:=flag; end; begin assign(input,'chemistry.in'); reset(input); assign(output,'chemistry.out'); rewrite(output); readln(q); readln(p); for i:=1 to p do readln(v[i]); for i:=1 to p-1 do for j:=i+1 to p do if v[i]>v[j] then begin k:=v[i]; v[i]:=v[j]; v[j]:=k; end; for maxd:=1 to 10 do begin fillchar(f,sizeof(f),255); f[0]:=0; if check then begin write(maxd); for i:=1 to maxd do write(' ',v[t[i]]); writeln; break; end; end; close(input); close(Output); end.
3、美丽的星空(physics)
问题描述
有一天,物理老师递给dsqwwe一张纸,神秘的说:”你要是把这个做出来,以后就不用交积累本了,否则,每天都交”,dsqwwe一阵狂喜,看都没看就答应了。仔细研究后才发现,物理老师的阴谋,但好几周未写积累本的他不能失败,于是,他想让你帮他编个程序。纸上的难题是这样的:
这张纸上画了一个n*m的星空图,当然,图中有许多的星座。一个星座是指一群连通的星组成的非空集合,所谓连通是指水平,垂直或者对角相邻。一个星座不能是另一个更大星座的一部分,星座可以相似(similar)。如果两个星座有相同的形状,而且包括相同数目的星体,那么不管其方向性如何,就算相似。一般而言,星座可能的方向有八个,如图所示
纸上的天体图是一个由字符0和1组成的二维矩阵,字符1表示所在的位置有一颗星;字符0表示该位置上没有星.给定一份天体图,用同一个小写英文标识相似的所有星座。相似的星座必须用相同的字母标识,不同的星座表示为不同的字母。标识一个星座,就是将其中各星体对应的字符1替换为相应的小写字母。
输入文件
文件的前两行分别记录了天体图的宽度m、深度n。而天体图则是由接下来的n行表示,每行包括m个字符
输出文件
输出文件记录了天体图与输入相似,不同之处在于,各个星座按照“任务”中的要求进行了标识。对于同一个输入文件,可能会有很多不同的标识,此时,输出字典序最小的标识。
样例输入
23
15
10001000000000010000000
01111100011111000101101
01000000010001000111111
00000000010101000101111
00000111010001000000000
00001001011111000000000
10000001000000000000000
00101000000111110010000
00001000000100010011111
00000001110101010100010
00000100110100010000000
00010001110111110000000
00100001110000000100000
00001000100001000100101
00000001110001000111000
样例输出
a000a0000000000b0000000
0aaaaa000ccccc000d0dd0d
0a0000000c000c000dddddd
000000000c0b0c000d0dddd
00000eee0c000c000000000
0000e00e0ccccc000000000
b000000e000000000000000
00b0f000000ccccc00a0000
0000f000000c000c00aaaaa
0000000ddd0c0b0c0a000a0
00000b00dd0c000c0000000
000g000ddd0ccccc0000000
00g0000ddd0000000e00000
0000b000d0000f000e00e0b
0000000ddd000f000eee000
数据范围
0 <= m <= 100
0 <=n <= 100
0 <= 星座的数目 <= 500
0 <= 不相似的星座数目 <= 26 (a..z)
1 <= 各星座包含的星体数目 <= 160
Hint
样例输出
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define INF 2147483647 using namespace std; typedef int node[110][110]; int d[8][2]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}}; int width,height; char map[110][110]; bool v[110][110]; int q[1000000][3]; int h[310],w[310]; node p[310]; int l,r; int ans; int max(int a,int b){return a>b?a:b;} int min(int a,int b){return a<b?a:b;} void color(char x){ for (int i=1;i<=r;i++){ map[q[i][0]][q[i][1]]=x; } } bool same(node a,node b,int ha,int wa){ for (int i=1;i<=ha;i++){ for (int j=1;j<=wa;j++){ if (a[i][j]!=b[i][j]) return false; } } return true; } void swap(int &a,int &b){ int c=a;a=b;b=c; } void turnright(node &a,int &ha,int &wa){ node b; memset(b,0,sizeof(b)); for (int i=1;i<=ha;i++){ for (int j=1;j<=wa;j++){ b[j][ha-i+1]=a[i][j]; } } memcpy(a,b,sizeof(b)); swap(ha,wa); } void turnopposite(node &a,int &ha,int &wa){ node b; memset(b,0,sizeof(b)); for (int i=1;i<=ha;i++){ for (int j=1;j<=wa;j++){ b[i][wa-j+1]=a[i][j]; } } memcpy(a,b,sizeof(b)); } void BFS(int a,int b){ int x,y; node nc; l=1;r=1; q[l][0]=a; q[l][1]=b; v[a][b]=true; while (l<=r){ x=q[l][0]; y=q[l][1]; for (int i=0;i<8;i++){ int tx=x+d[i][0]; int ty=y+d[i][1]; if (map[tx][ty]=='1' && !v[tx][ty]){ q[++r][0]=tx; q[r][1]=ty; v[tx][ty]=1; } } l++; } int minh=INF,minw=INF,maxh=-INF,maxw=-INF; for (int i=1;i<=r;i++) minh=min(minh,q[i][0]); for (int i=1;i<=r;i++) minw=min(minw,q[i][1]); for (int i=1;i<=r;i++) maxh=max(maxh,q[i][0]); for (int i=1;i<=r;i++) maxw=max(maxw,q[i][1]); int nh=maxh-minh+1; int nw=maxw-minw+1; memset(nc,0,sizeof(nc)); for (int i=1;i<=r;i++){ x=q[i][0]-minh+1; y=q[i][1]-minw+1; nc[x][y]=1; } for (int i=1;i<=4;i++){ for (int j=1;j<=ans;j++){ if (nh==h[j] && nw==w[j] && same(p[j],nc,nh,nw)){ color(j+96); return; } } turnright(nc,nh,nw); } turnopposite(nc,nh,nw); for (int i=1;i<=4;i++){ for (int j=1;j<=ans;j++){ if (nh==h[j] && nw==w[j] && same(p[j],nc,nh,nw)){ color(j+96); return; } } if (i!=4) turnright(nc,nh,nw); } ans++; memcpy(p[ans],nc,sizeof(nc)); h[ans]=nh; w[ans]=nw; color(ans+96); } void printmap(){ for (int i=1;i<=height;i++){ for (int j=1;j<=width;j++){ putchar(map[i][j]); } putchar('\n'); } } int main(){ freopen("physics.in","r",stdin); freopen("physics.out","w",stdout); scanf("%d%d",&width,&height); for (int i=1;i<=height;i++){ for(int j=1;j<=width;j++){ map[i][j]='0'; } } for (int i=1;i<=height;i++){ while (getchar()!='\n'){;} for (int j=1;j<=width;j++){ map[i][j]=getchar(); } } for (int i=1;i<=height;i++){ for (int j=1;j<=width;j++){ if (map[i][j]=='1') BFS(i,j); } } printmap(); return 0; }
Day2
|
题目名称 |
chinese |
English |
Biology |
输入文件 |
chinese .in |
English .in |
Biology .in |
输出文件 |
chinese .out |
English .out |
Biology .out |
测试点数目 |
10 |
10 |
10 |
测试点分数 |
10 |
10 |
10 |
题目类型 |
传统 |
传统 |
传统 |
时间限制 |
1s |
1S |
1S |
空间限制 |
128MB |
128MB |
128MB |
C++同学禁止使用stl库
文件总大小不得大于50kb
由于第一次出这样的两试题,可能难度把握不好,请大家见谅。
答疑请用飞鸽
1、 诗歌的主题(chinese)
问题描述
众所舟舟知,zsz童鞋是语文课代表,此人ws至极,仗着职权之便,从来不交语文积累本,终于有一天,他被老班发现了(乌卡卡卡卡卡)。于是老班给他出了一个特别的诗歌鉴赏题:
为了方便描述,我们将诗歌中的字用数字代表,现在zsz要找出诗歌中长度最长的一个主题。
诗歌的主题要满足以下几个要求:
1、 它是整首诗歌的一个字串
2、 长度至少为5
3、 在诗歌中必须重复出现(可能经过诗人的加工,加工方法见下文)
4、 重复出现的同一主题不能有公共部分
加工的意思是主题序列中的每个数字,都被加上或减去了同一个整数。给定一首诗歌,计算其中最长的主题长度。
输入格式
第一行一个整数n,表示诗歌的长度
下面的每一行包含20个整数,表示诗歌的内容,最后一行的数的个数可能小于n,总之,一共n个整数。
输出格式
一个整数,即最长的主题长度。如果找不到符合要求的主题,输出0
样例输入
30
25 27 30 34 39 45 52 60 69 79 69 60 52 45 39 34 30 26 22 18
82 78 74 70 66 67 64 60 65 80
样例输出
5
数据范围
1<=n<=5000
1<=ai(每个数字)<=100
/* ID:abccbaz1 TASK:theme LANG:C++ */ #include <cstdio> #include <cstring> #include <iostream> #include <fstream> using namespace std; ifstream fin("chinese.in"); ofstream fout("chinese.out"); int n; int a[5001]; int f[5001],g[5001]; int ans; int main(){ fin>>n; for (int i=1;i<=n;i++) fin>>a[i]; a[0]=0x7fffffff; for (int i=1;i<=n;i++){ for (int j=1;j<i;j++){ if (a[i]-a[i-1]==a[j]-a[j-1] && g[j-1]<i-j-1){ f[j]=max(f[j],g[j-1]+1); ans=max(f[j],ans); } } memcpy(g,f,sizeof(g)); memset(f,0,sizeof(f)); } if (ans+1>=5){ fout<<ans+1<<endl; }else fout<<0<<endl; return 0; }
2、数学,又是数学(mathagain)
其实吧,大家也发现了,这六道题本来是一科一道的,但是呢,由于某某人比较……,就不顾某某人的反对抛弃了我们可爱的English,又出了一道math……
题目描述
Liukeke同学(我们敬爱滴亲爱滴可爱滴班长大人)最近又在忙着开班会(真是个工作狂),于是乎,数学学案就被抛到了九霄云外,直到预备铃打完,他才发现那张美丽的雪白的学案,眼看一场血案即将发生,他请你用最快的速度帮他算完第一题:
给定一个数串,数串的长度为n,现在将一个子串的每个数字之和定义为该子串的数串和,请你求出数串中有多少个子串的数串和为正数。
输入格式
第一行一个数n,表示数串的长度。
第二行一共n个数,表示数串中的每个数
输出格式
就一个数,表示数串中有多少个子串的数串和为正数。
样例输入
3
8 -9 2
样例输出
3
数据范围
30% n<=1000。
100% n<=100000。
program mathagain; type link=^rec; rec=record lch,rch:link; lnum,rnum,heap,data:longint; end; var tree:link; n,i,j,cost:longint; ans:int64; a,sum:array[0..200000] of longint; procedure right(var tree:link); var p:link; begin p:=tree^.lch; tree^.lch:=p^.rch; if (tree^.lch<>nil) then tree^.lnum:=p^.rnum else tree^.lnum:=0; p^.rch:=tree; p^.rnum:=tree^.rnum+tree^.lnum+1; tree:=p; end; procedure left(var tree:link); var p:link; begin p:=tree^.rch; tree^.rch:=p^.lch; if (tree^.rch<>nil) then tree^.rnum:=p^.lnum else tree^.rnum:=0; p^.lch:=tree; p^.lnum:=tree^.lnum+tree^.rnum+1; tree:=p; end; procedure insert(var tree:link;data:longint); begin if (tree=nil) then begin new(tree); tree^.heap:=random(maxlongint); tree^.data:=data; tree^.lch:=nil; tree^.rch:=nil; tree^.lnum:=0; tree^.rnum:=0; end else begin if (data<tree^.data) then begin insert(tree^.lch,data); inc(tree^.lnum); if (tree^.lch^.heap<tree^.heap) then right(tree); end else begin insert(tree^.rch,data); inc(tree^.rnum); if (tree^.rch^.heap<tree^.heap) then left(tree); end; end; end; procedure search(tree:link;data:longint); begin if (tree=nil) then exit; if (tree^.data<=data) then begin search(tree^.rch,data); end else if (tree^.data>data) then begin inc(ans,tree^.rnum+1); search(tree^.lch,data); end; end; procedure del(var tree:link;data:longint); begin if (tree=nil) then exit; if (tree^.data=data) then begin if (tree^.lch=nil)or(tree^.rch=nil) then begin if (tree^.lch=nil) then tree:=tree^.rch else tree:=tree^.lch; end else begin if (tree^.lch^.heap<tree^.rch^.heap) then begin right(tree); dec(tree^.rnum); del(tree^.rch,data); end else begin left(tree); dec(tree^.lnum); del(tree^.lch,data); end; end; end else begin if (tree^.data>data) then begin dec(tree^.lnum); del(tree^.lch,data); end else if (tree^.data<=data) then begin dec(tree^.rnum); del(tree^.rch,data); end; end; end; begin assign(input,'mathagain.in'); reset(input); assign(output,'mathagain.out'); rewrite(output); readln(n); tree:=nil; randomize; ans:=0; for i:=1 to n do begin read(a[i]); sum[i]:=sum[i-1]+a[i]; insert(tree,sum[i]); end; readln; cost:=0; for i:=1 to n do begin search(tree,cost); inc(cost,a[i]); del(tree,sum[i]); end; writeln(ans); close(input); close(output); end.
3、烦人的生物(biology)
题目描述
最后一题了,当然是要让我们的jz出场了(jz就是zj,zj就是jz,至于为什么……&),处于某种ws的对知识的渴望,jz非常喜欢生物。
现在jz发现自己本身就是个非常纠结的动物,jz发现如果把自身的细胞排成一排,根据细胞某种性质的不同,可将细胞分成两类,如果将这两类细胞分别用0/1表示,就得到了一个能表示自身细胞的0/1串。jz发现了自身的0/1是个奇妙的东西,就决定出个题来恶心你。
他会告诉你自身0/1串的长度m,和给出你的描述0/1串的语句条数n。
每条语句都符合以下格式:
a, ,b, ,even/odd
表示自身 0/1串中第a~b位上数字的和是偶数/奇数
jz想让你说出最早出现的与前面描述矛盾的语句是谁,你能解决这个问题吗?
输入格式
第一行,一个整数m,表示jz自身0/1串的长度
第二行,一个整数n,表示jz给出的语句数目。
第三行~,共n行,为jz给出的语句,保证按上文所述格式给出。
输出格式
输出zj最早说出的与前面语句矛盾的语句的位置-1
Eg:如果该语句是第2句,输出1
如果没有矛盾,则输出n
样例输入
10
5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd
样例输出
3
数据范围
40% m<=1000000
100% m<=maxlongint
100% n<=5000
#include <cstdio> #include <cstring> #include <iostream> #define HASH 99998 using namespace std; int n,m; int fa[301000]; int len[301000]; int hash[HASH+2]; int Hash(int x){ int t=x % HASH; while (hash[t]!=-1 && hash[t]!=x){ t=(t + 1) % HASH; } hash[t]=x; return t; } int get(int x){ if (fa[x]==x) return fa[x]; int t=fa[x]; fa[x]=get(t); len[x]=(len[x]+len[t]+2) % 2; return fa[x]; } bool check(int a,int b,int e){ int x=get(a); int y=get(b); if (x!=y){ fa[y]=x; len[y]=(len[a]-len[b]+2+e) % 2; return false; }else if (x==y){ if ((len[a]-len[b]+2) % 2!=e) return true; return false; } return false; } int main(){ freopen("biology.in","r",stdin); freopen("biology.out","w",stdout); cin>>n>>m; for (int i=1;i<=300000;i++) fa[i]=i; memset(hash,255,sizeof(hash)); for (int i=1;i<=m;i++){ int a,b; string c; cin>>a>>b>>c; int even=(c=="even")?0:1; a=Hash(a-1); b=Hash(b); if (check(a,b,even)){ cout<<i-1<<endl; return 0; } } cout<<m<<endl; return 0; }