题目名称

Lsbm

Escape

Happy

Change

输入文件

Lsbm.in

Escape.in

Happy.in

Change.in

输出文件

Lsbm.out

Escape.out

Happy.out

Change.out

测试点数目

10

10

10

10

测试点分数

10

     

题目类型

传统

传统

传统

传统

时间限制

1s

1s

1s

1s

空间限制

128M

128M

128M

128M

一.Sss之零食被没

众所周知,sss同学曾经被信老师没收过零食。话说那是个只有信息组在的自习课,sss和兆哥坐在一起,sss偷偷摸出隐藏许久的零食,冲兆哥坏坏一笑(哈哈,我有你没有!)兆哥小声对sss说:“老班!”sss又坏坏一笑(哼,想骗我?)sss正欲将袋打开,说时迟,那时快,老班的手早已将它夺走,可怜的sss,连袋都没打开就被没收了。后来sss恍然大悟,原来今天是他的黑色星期五!于是sss想算一下以后的某一天是星期几,如果是星期五,他绝不会再吃零食了!

输入格式:

一行三个整数Y,M,D,表示要计算的日期的年,月,日。

输出格式:

输出sunday,monday,tuesday,wednesday,thursday,friday,saturday中得一个表示答案。(首字母大写)

样例输入:

2011 10 19

样例输出:

Wednesday

范围:

保证数据时间晚于2011年10月18日,、早于99999年12月31日

 

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int year,month,day;
int dp[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}};
string s[8];
int nian(int x){
    if ((x%400==0) || (x%4==0 && x%100!=0)) return 366;
    return 365;
}
int run(int x){
    if ((x%400==0) || (x%4==0 && x%100!=0)) return 1;
    return 0;
}
int getnext(int y,int m,int d){
    bool flag=0;
    if (m>10) flag=true;
    else if (m==10 && d>18) flag=true;
    if (flag) return y;else return y-1;
}
int main(){
    freopen("lsbm.in","r",stdin);
    freopen("lsbm.out","w",stdout);
    s[1]="Monday";
    s[2]="Tuesday";
    s[3]="Wednesday";
    s[4]="Thursday";
    s[5]="Friday";
    s[6]="Saturday";
    s[0]="Sunday";
    cin>>year>>month>>day;
    if (year==2011 && month==10 && day==18){
                   cout<<s[2]<<endl;
                   return 0;
    }
    int st=2;
    int y=2011,m=10,d=18;
    while (y!=year  || m!=month || d!=day){
          st++;
          st %=7;
          d++;
          if (d>dp[0][m]){
                       m++;
                       d=1;
          }
          if (m==13){
                     break;
          }
    }
    if (y==year && m==month && d==day){
                cout<<s[st]<<endl;
                return 0;
    }
    int t=2012;
    while (t<year){
          st=(st+(nian(t) % 7)) % 7;
          t++;
    }
    y=year,m=1,d=1;
    t=run(year);
    while (y!=year || m!=month || d!=day){
          st++;
          st %=7;
          d++;
          if (d>dp[t][m]){
                          m++;
                          d=1;
          }
    }
    cout<<s[st]<<endl;
    return 0;
}

 

二.sss之逃跑未遂

众所周知,sss同学曾经被尼玛大哥抓过。话说那是一个下午大课间,sss同学没有做眼保健操就去超市买东西了,可是不小心碰上了尼玛大哥,sss0.01秒的反应时间后,撒腿就往后跑,他的后面是一条柏油马路,马路不是平坦的,是建在钢板上的,钢板又是建在一些地基上的,每一个地基都有一个高度,一块钢板是平行的,是从一个地基铺到另一个地基的(所以中间的地基不能高于此位置的钢板)(可以是上坡,也可以是下坡),但这两个地基之间最多有k-1个地基。问sss从逃跑点(起点)到教学楼(终点)的路中最少用到几个地基。

输入格式

第一行是N和K,2<=N<=5000,1<=K<=N-1。接下来N行,按顺序是地基的高度h,0<=h<=1000000000。

输出格式

一个整数,表示最少地基数,第一个(起点)和最后一个(终点)一定是被用的地基。

样例输入

13 4

0

1

0

2

4

6

8

6

8

8

9

11

12

样例输出

5

 

#include <cstdio>
#include <iostream>
using namespace std;
int n,k;
int a[5001];
int f[5001];
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a>b?a:b;}
int main(){
    freopen("escape.in","r",stdin);
    freopen("escape.out","w",stdout);
    cin>>n>>k;
    for (int i=1;i<=n;i++) cin>>a[i];
    f[1]=1;
    for (int i=2;i<=n;i++){
        f[i]=9999999;
        double mi=999999999;
        for (int j=i-1;j>=max(1,i-k);j--){
            if (mi>=(a[j]-a[i])/(double)(j-i)){
                                       f[i]=min(f[i],f[j]+1);
                                       mi=(a[j]-a[i])/(double)(j-i);
            }
        }
    }
    printf("%d\n",f[n]);
    return 0;
}

 

三. Sss之XX洗浴

众所周知,这个就不扩展了……

自从这次被抓以后,sss同学很不服气。回家后,sss就开始了他的计划!(你不让我洗浴,我就在家洗个痛快!)sss打算在自家的院子里修一个洗浴池,当然他希望洗浴池越大越好。但是院子里有sss喜欢的一些植物,他不想毁掉任一颗植物,所以洗浴池不能将植物的位置占掉。Sss的院子和洗浴池都是矩形的,浴池要完全处在院子里,并且浴池的轮廓要与院子的轮廓平行或重合。每个植物可以看做一个点,浴池不能覆盖任何一个植物点,但是植物点可以在浴池的边上,请问sss的浴池最大能修多大.

输入格式:

输入文件的第一行包含两个整数l和w,分别表示院子的长和宽。文件的第二行包含一个整数n,表示植物的数量。以下n行每行包含两个整数x和y,表示一个植物点的坐标。所有植物点都位于院子内,即:0<=x<=l,0<=y<=w。

输出

输出文件仅一行,包含一个整数s,表示浴池的最大面积。

样例输入

10 10

4

1 1

9 1

1 9

9 9

样例输出

80

提示

各个测试点1s0<=n<=5

#include <cstdio>
#include <algorithm>
using namespace std;
int w,l;
int n;
struct node{
       int x,y;
}a[5100];
int ans;
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a>b?a:b;}
int cmp(node a,node b){
    if (a.x!=b.x) return a.x<b.x;
    return a.y<b.y;
}
int main(){
    freopen("happy.in","r",stdin);
    freopen("happy.out","w",stdout);
    scanf("%d%d%d",&w,&l,&n);
    for (int i=1;i<=n;i++){
        scanf("%d%d",&a[i].x,&a[i].y);
    }
    a[++n].x=0;
    a[n].y=w;
    a[++n].x=l;
    a[n].y=w;
    a[++n].x=0;
    a[n].y=0;
    a[++n].x=l;
    a[n].y=0;
    sort(a+1,a+1+n,cmp);
    for (int i=1;i<n;i++){
        int l=a[i].x;
        int u=w,d=0;
        bool flag=false;
        for (int j=i+1;j<=n;j++){
            if (a[j].x>a[i].x){
                               if (!flag) ans=max(ans,(a[j].x-l)*(u-d));
                               else ans=max(ans,max((a[j].x-l)*(u-a[i].y),(a[j].x-l)*(a[i].y-d)));
                               if (a[j].y>a[i].y) u=min(u,a[j].y);
                               else if (a[i].y>a[j].y) d=max(d,a[j].y);
                               else if (a[i].y==a[j].y) flag=true;
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}

0001<=l,w<=30000

 

 

 

四:sss之转化模式

众所舟舟知……sss同学会转换模式,我们对两种模式的定义为;♀♂,其实sss的模式转换是建立在他身体的细胞模式转换之上的,比如说这里有6*6的细胞:

♀♂♀♂♀♂

♀♂♀♂♀♂

♀♂♀♂♀♂

♀♂♀♂♀♂

♀♂♀♂♀♂

♀♂♀♂♀♂

所以大家就知道为什么sss的模式总是介于两者之间了,因为他的每个细胞的模式不一样!

Sss的细胞和sss一样有很多的坏毛病,当一个细胞转换模式时,他也会使它上,下,左,右四个细胞转换模式,但是仍算转换一步。比如,对于上图(1,2)的转换模式后总的模式变为:

♂♀♂♂♀♂

♀♀♀♂♀♂

♀♂♀♂♀♂

♀♂♀♂♀♂

♀♂♀♂♀♂

♀♂♀♂♀♂

(3,3)转换模式后总的模式变为:

♀♂♀♂♀♂

♀♂♂♂♀♂

♀♀♂♀♀♂

♀♂♂♂♀♂

♀♂♀♂♀♂

♀♂♀♂♀♂

好了,现在问题来了,sss现在想把n*n的细胞全部转换成♂模式,若不能转化输出‘NO’,若能输出最少需要几步。

注意:为了描述生动应用了♀♂符号,但word中的符号与pascal中的不一样,读入以pascal中的为准,pascal中为了转换方便最好使用ASCII码,♂11,♀12.

样例输入:(数据请粘贴change.in)(粘到pascal中就能看到了)

3

♂♀♂

♀♀♀

♂♀♂

样例输出:

1

范围:

50% n<=5;

100% n<=10;

 

#include <cstdio>
#include <cstring>
#define INF 200000000
int a[10],b[10];
int n;
bool check(){
     for (int i=0;i<n;i++){
         if (b[i]) return false;
     }
     return true;
}
int main(){
    freopen("change.in","r",stdin);
    freopen("change.out","w",stdout);
    scanf("%d",&n);
    for (int i=0;i<n;i++){
        while (getchar()!='\n'){;}
        for (int j=0;j<n;j++){
            char c;
            scanf("%c",&c);
            a[i]=(a[i] << 1) + (c==12);
        }
    }
    int ans=INF;
    for (int i=0;i<1 << n;i++){
        int tot=0;
        memcpy(b,a,sizeof(a));
        for (int j=0;j<n;j++)
        if (i & (1 << j)){    
            ++tot;
            b[0] ^= 1 << j;
            if (j>0) b[0] ^= 1 << (j-1);
            if (j<n-1) b[0] ^= 1 << (j+1);
            if (n>1) b[1] ^= 1 << j;
        }
        for (int j=1;j<n;j++){
            for (int k=0;k<n;k++){
                if (b[j-1] & (1 << k)){
                         ++tot;
                         b[j] ^= 1 << k;
                         b[j-1] ^= 1 << k;
                         if (k>0) b[j] ^= 1 << (k-1);
                         if (k<n-1) b[j] ^= 1 << (k+1);
                         if (j<n-1) b[j+1] ^= 1 << k;
                }
            }
        }
        if (check() && tot<ans) ans=tot;
    }
    if (ans==INF) printf("NO\n");else printf("%d\n",ans);
    return 0;
}