noip2005解题报告

(说个废话,NOIP2005简直水到家了,轻轻松松400啊,只叹出生的太迟了。。。)

一、陶陶摘苹果

陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果。苹果成熟的时候,陶陶就会跑去摘苹果。陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。
现在已知10个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹果的数目。假设她碰到苹果,苹果就会掉下来。

 

 

 


输入包括两行数据。第一行包含10100200之间(包括100200)的整数(以厘米为单位)分别表示10个苹果到地面的高度,两个相邻的整数之间用一个空格隔开。第二行只包括一个100120之间(包含100120)的整数(以厘米为单位),表示陶陶把手伸直的时候能够达到的最大高度。

 

输出包括一行,这一行只包含一个整数,表示陶陶能够摘到的苹果的数目。


100 200 150 140 129 134 167 198 200 111

110

5

废柴题目,我都不知道NOIP办公室怎么想的,出这个题目,就是用陶陶的身高+板凳一个一个比

#include
using namespace std;
int n,ans;
int catche;
int a[11];
int main()
{
  catche=30;
   for(int i=1;i<=10;i++)cin>>a[i];
   cin>>n;
    catche+=n;
    for(int i=1;i<=10;i++)if(a[i]<=catche)ans++;
    cout<<ans;
    return 0;
}
	
二、校门外的树

某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即012……L,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。

输入第一行有两个整数L1<=L<=10000)和M1<=M<=100),L代表马路的长度,M代表区域的数目,LM之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。

输出包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。


500 3

150 300

100 200

470 471



298

人家说傻子活的很快乐,在这里表现的淋漓尽致,千万不要想多难,其实就是开个数字,如果被砍掉就变成1,然后全部加起来,再用总数减去

#include
using namespace std;
int n,i,ans,all,r,l,j;
int c[1000001];
int main()
{
    cin>>all>>n;
    for(i=1;i<=n;i++)
    {cin>>l>>r;
    for(j=l;j<=r;j++)c[j]=1;
    }
    for(j=0;j<=all;j++)
    if(c[j]==0)ans++;
    cout<<ans;
    return 0;
}
三、采药

辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。

如果你是辰辰,你能完成这个任务吗?

输入第一行有两个整数T1<=T<=1000)和M1<=M<=100),用一个空格隔开,T代表总共能够用来采药的时间,M代表山洞里的草药的数目。接下来的M行每行包括两个在1100之间(包括1100)的整数,分别表示采摘某株草药的时间和这株草药的价值。

输出包括一行,这一行只包含一个整数,表示在规定的时间内,可以采到的草药的最大总价值。

70 3

71 100

69 1

1 2

3

【数据规模】

对于30%的数据,M<=10

对于全部的数据,M<=100

疯了疯了,彻底疯了,这不就是最傻的01背包吗?

套公式!f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+v[i]);

#include
using namespace std;
int t,n;
int v[101],w[101];
int f[101][1001];
int i,j;
int main()
{
cin>>t>>n;
    for(i=1;i<=n;i++)cin>>w[i]>>v[i];
    for(i=1;i<=n;i++)
        for(j=1;j<=t;j++)
         if(j<w[i])f[i][j]=f[i-1][j];
        else f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+v[i]);
    cout<<f[n][t];
        return 0;
}
四、循环

乐乐是一个聪明而又勤奋好学的孩子。他总喜欢探求事物的规律。一天,他突然对数的正整数次幂产生了兴趣。

众所周知,2的正整数次幂最后一位数总是不断的在重复24862486……我们说2的正整数次幂最后一位的循环长度是4(实际上4的倍数都可以说是循环长度,但我们只考虑最小的循环长度)。类似的,其余的数字的正整数次幂最后一位数也有类似的循环现象:


循环
循环长度

2
2
486
4

3
3971
4

4
46
2

5
5
1

6
6
1

7
7931
4

8
8426
4

9
91
2


这时乐乐的问题就出来了:是不是只有最后一位才有这样的循环呢?对于一个整数n的正整数次幂来说,它的后k位是否会发生循环?如果循环的话,循环长度是多少呢?

 

注意:

1
如果n的某个正整数次幂的位数不足k,那么不足的高位看做是0

2
如果循环长度是L,那么说明对于任意的正整数ana次幂和a+L次幂的最后k位都相同。


输入只有一行,包含两个整数n1<=n<10100)和k1<=k<=100),nk之间用一个空格隔开,表示要求n的正整数次幂的最后k位的循环长度。

输出包括一行,这一行只包含一个整数,表示循环长度。如果循环不存在,输出-1

32 2

4

【数据规模】

对于30%的数据,k<=4

对于全部的数据,k<=100

高精度乘法,哎,脑残了吧?

Type

  Arr=Array[1..101] Of Integer;

Var

  i,j,p,k,code,L,num,tp:Integer;

  s: String;

  a,aa,time,b,temp:Arr;

//高精度乘法

Procedure Mutiply(a, b:Arr;Var c:Arr;t:Integer);

Var

  i, j: Integer;

Begin

  FillChar(c, SizeOf(c), 0);

  For i:=1 To t Do

    For j:=1 To t-i+1 Do

    Begin

      c[i+j-1]:=a[i]*b[j]+c[i+j-1];

      c[i+j]:=c[i+j]+c[i+j-1] Div 10;

      c[i+j-1]:=c[i+j-1] Mod 10;

    End;

End;

//高精度乘法,计算总次数,L表示次数的长度

Procedure Mutiply(a:Arr;b:Integer;Var c:Arr;Var L:Integer);

Var

  i: Integer;

Begin

  FillChar(c,SizeOf(c),0);

  For i:=1 To L Do

  Begin

//这里是乘,因为如果个位需要5次,十位需要5次,那么肯定需要25次才可以满足个位和十位的要求

c[i]:=c[i]+a[i]*b;

    c[i+1]:=c[i] Div 10;

    c[i]:=c[i] Mod 10;

  End;

  If c[L+1]<>0 Then

    Inc(L);

End;

 

Begin

  //重定位标准输入和标准输出设备

  Assign(Input, 'circle.in');

  Assign(Output, 'circle.out');

  ReSet(Input);

  ReWrite(Output);

 

  ReadLn(s);

  //分两部分截取s,和循环位数K

  Val(Copy(s, Pos(' ', s)+1, Length(s)-Pos(' ', s)), k, code);

  Delete(s, Pos(' ', s), Length(s)-Pos(' ', s)+1);

//将S倒转转化为数值存在数值类型的数组中以便于计算

  For i:=1 To Length(s) Do

    Val(s[i], a[Length(s)-i+1], code);

  aa:=a;

//初始化次数数组

  FillChar(time, SizeOf(time), 0);

  time[1] := 1;

  L := 1;

//开始计算

  For i:=1 To k Do

  Begin

    //从一位开始对比,直到K位,b为比较的初始数组

    For j:=1 To i Do

      b[j] := aa[j];

    tp := b[i];//TP为比较的位的值

    num := 0;

    Repeat

      Mutiply(b, a, b, i);

      Inc(num);

    Until (num > 10) Or (b[i] = tp);

//超过10次则代表就是无法满足循环条件了,因为只有10个数0..9

    If (b[i] <> tp) Then Begin

      Write(-1);

      Close(Input);

      Close(Output);

      Halt(0);

    End;

//根据需要几次才能满足,变化基础的乘因子a

    temp := a;

    For j:=1 To num-1 Do

      Mutiply(a, temp, a, k);

 

    Mutiply(time, num, time, L);

  End;

//反输出time,表示最终需要次数

  For i:=L DownTo 1 Do Write(time[i]);

 

  Close(Input);

  Close(Output);

End.

实在无语,恨天晚生我3年啊!

你可能感兴趣的:(noip2005解题报告)