9.15NOIP模拟题

GRYZ 模拟考试套题 9.15

                                                                                                                                gryz信息组专场

题目名称

最初的最初

太

妃

糖

可执行文件名

eat

hwc

dance

sugar

输入文件

eat.in

hwc.in

dance.in

sugar.in

输出文件

eat.out

hwc.out

dance.out

sugra.out

时间限制

1s

0.2s

1s

0.5s

是否有部分分

无

无

无

无

满分

1000

100

100

100

空间限制

128M

128M

128M

128M

测试点数量

20

20

20

20

测试点分值

50

5

5

5

数据是否分层

否

是

是

否

 

不要相信出题人

注意事项:

1. 文件名(输入和输出文件名) 必须是英文小写。

2. 若无说明,对比方式均为忽略行末空格及文末回车的全文比较。

3. C/C++中函数 main()的返回值必须是 int,程序正常结束的返回

值必须是 0。

4. 评测环境为 cena 注意:windows 下 long long 输入输出请使用%I64d。

5. 编译时不打开任何优化选项。

6.本套题目不保证没有任何彩蛋。

另:题目难度与题目顺序无关!

 

 

 

 

 

最初的最初

题目描述:

思绪,漂浮,荒乱,不知去向。

那些记忆,凌乱的,盘旋于脑海,迟迟不肯离去。

以为,时间会带走一切,我拼命的拒绝着你虚假演绎的片段。

想忘记,忘记。

 

 

 

当一切又回到最初的最初,杂乱而又不知所措。hkd望着远处苍茫迷蒙的混沌,陷入了久久的沉思。忽而,一把巨斧划过天际,盘古破开了混沌,hkd也在之混沌破灭之际被巨斧斩断,身体一分为二,化为了两件先天至宝,随盘古一起落入了洪荒之中。

后来,鸿钧成圣,捡到了两件先天至宝------hkd的身体,他想要知道混沌魔神hkd身体大大小,但是众所周知,古代人的算数水平都比较差,聪明的你能帮助他解决问题吗?

输入描述:

一行。两个数x和y,分别表示hkd两段身体的大小。

输出描述:

一行,hkd身体的大小。

样例输入:

4  7

样例输出:

11

提示:

x<=100000000;

y<=100000000;

 

 题解:A+B

代码略 分值1000

 

 

太

题目描述:

残存的碎片却愈加清晰。

好久一段时间,记忆突然停顿了,脑子一片空白。

忘记此刻是何年何月,甚至忘记自己是谁,等待太久,一切都回不到最初的原点。

九年。

相遇,分离,重逢,再…… 从初始到末端。

如傻瓜般虔诚的追随在你左右

2333年,在银河系的某星球上,X军团和Y军团正在激烈地作战。在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai。当一个巨型机器人的装甲值减少到0或者以下时,这个巨型机器人就被摧毁了。X军团有M个激光武器,其中第i个激光武器每秒可以削减一个巨型机器人Bi的装甲值。激光武器的攻击是连续的。这种激光武器非常奇怪,一个激光武器只能攻击一些特定的敌人。Y军团看到自己的巨型机器人被X军团一个一个消灭,他们急需下达更多的指令。

输入描述:

一行 给你一个数n 表示下达的指令。

输出描述:

一行 请输出第n个回文数

样例输入:

输入样例#1:

2333

输出样例#1:

1334331

样例输出:

输入样例#2:

12345678987654321

输出样例#2:

23456789876543222234567898765432

提示:

对于 10%的数据 n<=100

对于 20%的数据 n<=100000000

对于 100%的数据 n<=1000000000000000000

 

 

/*
打表找规律
例如 23333
第一位减一,最后一位加一 13334
再对称 133343331 
如果第一位是1就往前移动一位若当前第一位还是0就变为9 
如果第一位为1并且第二位不是零就直接对称,否则对称的时候最后一位就不要
不要问我为什么....这是规律?理论依据呢...... 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;
char s[20];
int num[40],ans,flag;

int main()
{
    scanf("%s",s);
    int len=strlen(s);
    for(int i=len-1; i>=0; i--)
    {
        num[i+1]=s[i]-'0'+num[i+2]/10;
        num[i+2]%=10;
        if(i==0)    num[i+1]-=1;
        if(i==len-1)    num[i+1]+=1;
    }
    for(int i=1; i<=len; i++)
    {
        if(num[i]==0&&i==1)
        {
            ans=1;
            continue;
        }
        else if(num[i]==0&&i==2&&ans)    flag=1,cout<<"9";
        else cout<<num[i];
    }
    if(ans==1&&flag!=1)    len=len;
    else    len-=1;
    for(int i=len; i>=1; i--)
    {
        if(num[i]==0&&i==1)    continue;
        else if(num[i]==0&&i==2&&ans)    cout<<"9";
        else cout<<num[i];
    }
}

 

 

 

 妃

题目描述:

回忆的章节错乱不堪,想要收拾那些画面用来重温,却显得七零八乱。

整个人是麻木的,记忆也跟着苍白。

曾留下太多太深的足迹在心里。

刻意隐瞒,隐藏,隐忍着……

用近乎笨拙的方式隐身荒芜的背后,一直在原地徘徊。

决绝的用极端的方式否定了一切的伤痕和不舍, 清楚的听见自己心碎的声音。

一次次对灵魂华丽的自残,壮观而且荒谬。

我想我还是做错了,一味强求,不想离开你。

众所周知,三校区有一项优雅的大课间活动——广场舞。广场舞在以前是十分好跳的,同学们只要随着音乐翩翩起舞即可。但是三区校长为了增加广场舞的趣味性和可观性,勒令同学们摞成一摞跳操。同学们碍于各班班长的淫威只得同意了,同学们在跳操时是这样纸的,30个人摞成一摞(因为学校人数太少了,(*^__^*) ),摞成了n摞:

校长会偷偷的窝在小黑屋里,放各种颜色的烟花来指挥跳舞。校长最多可以燃放30个烟花,烟花有四种颜色,分别可以指挥所有的同学向东,西,南,北各移动一个格。但是这样跳操太累了,同学们都想偷懒,当一摞同学最下面的同学移动到教学楼时,这摞同学最上面的学生会跳到教学楼顶层,如下图

 

同学们想要尽可能多的偷懒,于是找到了你,总校后勤烟花爆竹管制处处长。

因为校长的烟花都是由你提供的,而校长只会按照你提供的烟花的顺序去燃放烟花,请你给出最多可以有几名同学偷懒,和此时燃放烟花的顺序。顺序用E,W,S,N表示指挥东西南北各种不同颜色的烟花。若有多个相同的,输出字典序最小的。

输入描述:

第1行3个整数n,m,k,描述同学摞成了几摞,教学楼的个数,校长可燃放的烟花的个数。

第2到1+n行每行两个整数x,y,描述n摞同学开始时的坐标。

第n+2到n+m+1行每行两个整数x,y,描述m个教学楼的坐标。

输出描述:

两行。

第一行 :最多能偷懒的学生的个数。

第二行 :此时燃放烟花的方案。

样例输入:

3 6 3

3 4

6 2

5 7

8 2

9 2

6 4

5 4

6 7

8 7

样例输出:

6

EEE

提示:

10%的数据,n<=1000,m<=1000,k<=5

40%的数据,n<=1000,m<=1000,k<=10

70%的数据,n<=1000;m<=1000;k<=20

100%的数据,n<=1000,m<=1000,k<=30,0<=x<=10000,0<=y<=10000

 

洛谷 P2905

 

/*
一到比较好的动态规划
dp[k][i][j]表示吹k次哨 纵向移动了i-31步,横向移动了j-31步,所能拯救的最多的牛的数量。
当j-31<0时,说明是向西移动,反之向东移动。i-31也是同理的。
转移显然 预处理和输出麻烦 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>

#define N 1507
#define inf 0x3f3f3f3f

using namespace std;
int n,m,K,ans;
int dx[4]={1,0,0,-1};
int dy[4]={0,1,-1,0};
char step[40][64][64];
char C[4]={'W','S','N','E'};
int cnt[64][64],dp[40][64][64];
int cawx[N],cawy[N],grax[N],gray[N];

inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

int max(int a,int b,int c,int d)
{
    return max(max(a,b),max(c,d));
}

void init()
{
    n=read();m=read();K=read();
    for(int i=1;i<=n;i++) cawx[i]=read(),cawy[i]=read();
    for(int i=1;i<=m;i++) grax[i]=read(),gray[i]=read();
    for(int i=1;i<=n;i++)
      for(int j=1;j<=m;j++)
        {
            int cx=cawx[i]-grax[j];
            int cy=cawy[i]-gray[j];
            if(abs(cx)<=30 && abs(cy)<=30) //因为k<=30,所以当有一个方向的距离大于30,就不用考虑了,因为一定不可能走到
            cnt[cx+31][cy+31]++;//否则cnt记录走纵向i步横向走j步所能拯救的牛的数量. 
        }
}

void work()
{
    for(int k=0;k<=K;k++)
      for(int i=0;i<=62;i++)
        for(int j=0;j<=62;j++)
           dp[k][i][j]=-inf,step[k][i][j]='Z';
    dp[0][31][31]=0;
    //因为他可以向上下左右走,为了防止负坐标的出现,我们把一开始时的原点坐标当做(31,31).
    for(int k=1;k<=K;k++)
      for(int i=1;i<=61;i++)//可能向左向右30步,所以循环61次 
        for(int j=1;j<=61;j++)
          dp[k][i][j]=cnt[i][j]+max(dp[k-1][i+1][j],dp[k-1][i-1][j],dp[k-1][i][j+1],dp[k-1][i][j-1]);
          
     for(int i=1;i<=61;i++)
       for(int j=1;j<=61;j++)
         ans=max(ans,dp[K][i][j]);
}

void solve()
{
    for(int i=1;i<=61;i++)
      for(int j=1;j<=61;j++)
        if(ans==dp[K][i][j]) step[K][i][j]='A'; //如果为纵向走i步横向走j步是一种可行的走法,记录以方便求字典序最小. 
          
    for(int k=K-1;k>=0;k--)//倒序找出所有可能的走法.
      for(int i=1;i<=61;i++)
        for(int j=1;j<=61;j++)
          for(int l=0;l<4;l++)
            {
                if(dp[k][i][j]+cnt[i+dx[l]][j+dy[l]]==dp[k+1][i+dx[l]][j+dy[l]]
                  && step[k+1][i+dx[l]][j+dy[l]]<'Z')
                    step[k][i][j]=C[l];
            }
    printf("%d\n",ans);
    
    int i=31,j=31;
    for(int k=0;k<K;k++)
    {
        cout<<step[k][i][j];
             if(step[k][i][j]=='E') i--;//坐标原点在右下角! 
        else if(step[k][i][j]=='W') i++;
        else if(step[k][i][j]=='S') j++;
        else if(step[k][i][j]=='N') j--;
    }return;
}

int main()
{
    init();
    work();
    solve();
    return 0;
}

 

 

 

 

糖

题目描述:

还是忘不了。

关于你的好与不好。

分分合合,早已成为习惯。

偏执的如同我的性格般执拗。

什么事都不做,安静的蜷缩在被窝里,细数自己的心碎与莫落。

最初的最初。

最后的最后。

Xxy每天都奋斗在跳楼梯的第一线,所以回宿舍后感到又累又饿,很快陷入了梦乡。在梦中,xxy进入了一个巨大的城堡。

这个题从叶子节点去算的话显然很困难,所以我们可以从xx所在的两个点开始倒着搞。 min和man记录每个节点最多和最少有多少个糖果才能让xx恰好吃到k只。然后,分别以这两个点为根节点,深搜一下求出所有的min和man。

接着,二分答案,求一下对于每个节点,g群糖果中符合条件的糖果的群数。最后,群数*k即为所求。

 

Xxy惊讶的发现,这座城堡有n个房间和m条走廊,走廊非常窄,只能单向通行。Xxy惊讶的发现在每个房间里都有一个魔法阵,魔法阵可以召唤魔法糖果,每个房间有且只有一个魔法糖果。每个魔法糖果都有一个饱腹值,xxy吃下糖果,就会增加饱腹值,不那么饿。与吃糖果相反的是,xxy需要穿越走廊才能吃到糖果,而每个走廊又有一定的疲惫值。Xxy想在吃完糖果后返回出发点。

Xxy现在非常的饥饿,所以她想吃到尽量多的糖果。但是,xxy也非常的累,所以她不想去浪费时间走更多的路。所以xxy希望在平均单位时间里,获得的饱腹值尽可能的大。请问xxy能得到的最大平均饱腹值是几?(因为xxy太饿了,所以他至少要吃掉2颗糖果)                                                                  

输入描述:

第一行:输入n,m,分别表示城堡中房间的数量,和走廊的数量。

第二行:输入n个数f,表示从1到n号房间内,每个房间里糖果能提供的饱腹值。

接下来m行,每行输入三个数x,y,z,表示房间x与y之间有走廊相连通。走完这条走廊的疲惫之为z。

输出描述:

一行,一个数ans表示xxy能得到的最大平均饱腹值,结果保留两位小数。

样例输入:

5 7

30

10

10

5

10

1 2 3

2 3 2

3 4 5

3 5 2

4 5 5

5 1 3

5 2 2

样例输出:

6.00

提示:

对于100%数据:2≤n≤1000,2≤m≤5000,1≤x,y≤n,1≤f,z≤1000。

 

 洛谷P2868

 

/*
这道题...算分数规划?
设一段路程的收益是F,花费是dis,则比率为 ΣF/Σdis=r
要找出最大的r
二分出r设为x ,将每条边的边权修改为 “目的地的收益f - 边长度dis*x”
然后SPFA检查图上是否有负环,有负环则x可以更优,答案可以增大。
*/
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#define N 100010

using namespace std;
const double eps=1e-5;

struct edge
{
    int v,nxt,w;
    double c;
} e[N<<1];
int head[N],f[N];
bool vis[N];
double dis[N];
int n,m,mct,u,v,w;

inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}

void add(int u,int v,int w)
{
    e[++mct].v=v;e[mct].nxt=head[u];e[mct].w=w;head[u]=mct;
}


bool SPFA(int u)
{
    vis[u]=1;
    for(int i=head[u]; i; i=e[i].nxt)
    {
        int v=e[i].v;
        if(dis[v]>dis[u]+e[i].c)
        {
            dis[v]=dis[u]+e[i].c;
            if(vis[v] || SPFA(v))
            {
                vis[v]=0;
                return 1;
            }
        }
    }vis[u]=0;return 0;
}

void judge(double r)
{
    for(int i=1; i<=mct; i++)
        e[i].c=(double)e[i].w*r-f[e[i].v];
    return;
}
bool check()
{
    for(int i=1; i<=n; i++)
        if(SPFA(i))return 1;
    return 0;
}
int main()
{
    n=read();m=read();
    for(int i=1; i<=n; i++) f[i]=read();
    for(int i=1; i<=m; i++)
    {
        u=read();v=read();w=read();
        add(u,v,w);
    }
    double l=0,r=100000,ans;
    while(r-l>eps)
    {
        double mid=(l+r)/2;
        judge(mid);
        if(check())
        {
            ans=mid;l=mid;
        }
        else r=mid;
    }
    printf("%.2f\n",ans);
    return 0;
}

 

 

 

posted @ 2017-09-15 15:51  安月冷  阅读(234)  评论(0)    收藏  举报