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)。如果两个星座有相同的形状,而且包括相同数目的星体,那么不管其方向性如何,就算相似。一般而言,星座可能的方向有八个,如图所示

clip_image002

纸上的天体图是一个由字符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

样例输出

clip_image004

 

 

#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

 

HZOI 2009校园生活

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

clip_image002

 

#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;
}