1. 程式人生 > >9.15模擬試題

9.15模擬試題

難度 -- 不堪 pop aac 限制 直接 判斷 連通

                     模擬考試套題

                                                                                                         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身體大大小,但是眾所周知,古代人的算數水平都比較差,聰明的你能幫助他解決問題嗎?

輸入描述:

一行。兩個數xy,分別表示hkd兩段身體的大小。

輸出描述:

一行,hkd身體的大小。

樣例輸入:

4 7

樣例輸出:

11

提示:

x<=100000000;

y<=100000000;

防AK好題、、(自己好好做做、、、、)

技術分享
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define ll long long 
using namespace std;
ll x,y,ans;
ll read()
{
    ll x=0,f=1; char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1; ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0; ch=getchar();}
    return x*f;
}
int main()
{
    freopen("eat.in","r",stdin);
    freopen("eat.out","w",stdout);
    x=read(),y=read();
    ans=x+y;
    printf("%I64d",ans);
    return 0;
}
AC‘代碼

題目描述:

殘存的碎片卻愈加清晰。

好久一段時間,記憶突然停頓了,腦子一片空白。

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

九年。

相遇,分離,重逢,再…… 從初始到末端。

如傻瓜般虔誠的追隨在你左右。

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

打表找規律

先打一個表

回文數的位數 回文數的個數
1位 1 2 3 4 5 6 7 8 9 9
2位 11 22 33 44 55 66 77 88 99 9
3位 101 111 121 131 141 151 161 171 181 191
202 212 222 232 242 252 262 272 282 292
。。。
909 919 929 939 949 959 969 979 989 999 90
4位 1001 1111 1221 1331 1441 1551 1661 1771 1881 1991
、、、
9009 9119 9229 9339 9449 9559 9669 9779 9889 9999 90
5位 10001 10101 10201 10301 10401 10501 10601 10701 10801 10901 9*10*10=900
6位 100001 、、、 9*10*10=900

我們可以發現這樣一個規律1位跟2位的回文數有9個,3位跟4位的有90個,5位跟6位的有900個,7位跟8位的有9000個,9位跟10位的有90000個

我們預處理出來到達每一位的回文數的個數,求一個前綴和,然後處理出來當前要求的第幾個回文數是幾位的數。也就是回文數的長度。

然後我們將回文數拆成兩半來進行分析,我們可以發現後一半是講前一半對稱過去的,並且影響回文數的大小(編號)的只與前面一半有關。

我們處理出來回文數的長度以後在看看他在當前長度裏是第幾個數,我們可以發現,這個數的前一半的大小正好等於他是當前長度裏的第幾個數-1+當前長度的第一個數。我們可以發現當長度為1的時候第一個數是從1開始的,為2的時候第一個數是從1開始的,為3從10開始,4從10開始,5從100開始、、、以此類推,我們又會發現一個規律,長度為n的數的前半段的第一個數是從10^((l+1)/2)開始的。那麽前一半的數的大小就是(10^((l+1)/2))+n-f[l-1]+1然後在根據長度的奇偶就可以知道後半段的數的大小。

技術分享
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define ll long long 
#define N 1000000000000000000LL
using namespace std;
ll n,s,f[1100],l,len,x;
ll read()
{
    ll x=0,f=1; char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1; ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0; ch=getchar();}
    return x*f;
}
ll qpow(ll n,ll k)
{
    ll res=1;
    while(k)
    {
        if(k&1) res=res*n;
        n=n*n;
        k=k>>1;
    }
    return res;
}
int main()
{
    freopen("hwc.in","r",stdin);
    freopen("hwc.out","w",stdout);
    n=read(); s=9;
    for(int i=1;;s*=10)
    {
        f[i]=f[i-1]+s; i++;
        f[i]=f[i-1]+s; i++;
        if(f[i-1]>=N) break;
    }
    for(int i=1;i<=n;i++)
     if(n<=f[i])
     {
         l=i;
         break;
         
     }
    len=l;
    n-=f[l-1];l=(l+1)/2;
    x=qpow(10,l-1)+n-1;
    printf("%I64d",x);
    if(len%2!=0) x/=10;
    while(x)
    {
        printf("%I64d",x%10);
        x/=10;
    }
    return 0;
}
AC代碼

題目描述:

回憶的章節錯亂不堪,想要收拾那些畫面用來重溫,卻顯得七零八亂。

整個人是麻木的,記憶也跟著蒼白。

曾留下太多太深的足跡在心裏。

刻意隱瞞,隱藏,隱忍著……

用近乎笨拙的方式隱身荒蕪的背後,一直在原地徘徊。

決絕的用極端的方式否定了一切的傷痕和不舍, 清楚的聽見自己心碎的聲音。

一次次對靈魂華麗的自殘,壯觀而且荒謬。

我想我還是做錯了,一味強求,不想離開你。

眾所周知,三校區有一項優雅的大課間活動——廣場舞。廣場舞在以前是十分好跳的,同學們只要隨著音樂翩翩起舞即可。但是三區校長為了增加廣場舞的趣味性和可觀性,勒令同學們摞成一摞跳操。同學們礙於各班班長的淫威只得同意了,同學們在跳操時是這樣紙的,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

題目描述:

還是忘不了。

關於你的好與不好。

分分合合,早已成為習慣。

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

什麽事都不做,安靜的蜷縮在被窩裏,細數自己的心碎與莫落。

最初的最初。

最後的最後。

Xxy每天都奮鬥在跳樓梯的第一線,所以回宿舍後感到又累又餓,很快陷入了夢鄉。在夢中,xxy進入了一個巨大的城堡。

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。

洛谷原題

https://www.luogu.org/problem/show?pid=2868

在洛谷上好好地70分被出題人卡成了5分(啊啊啊,全部超時!)

技術分享
#include<queue>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 51000
using namespace std;
bool vis[N];
int n,m,x,y,z,tot;
int c[N],num[N],head[N];
double ans,mid,l,r,w[N],dis[N];
int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1; ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0; ch=getchar();}
    return x*f;
}
struct Edge
{
    int next,to,from,dis;
}edge[N];
int add(int x,int y,int z)
{
    tot++;
    edge[tot].to=y;
    edge[tot].dis=z;
    edge[tot].next=head[x];
    head[x]=tot;
}
int spfa(int s)
{
    queue<int>q;
    memset(vis,0,sizeof(vis));
    memset(num,0,sizeof(num));
    memset(dis,0x3f,sizeof(dis));
    dis[s]=0,vis[s]=true; q.push(s);
    while(!q.empty())
    {
        x=q.front(),q.pop();vis[x]=false;
        for(int i=head[x];i;i=edge[i].next)
        {
            int t=edge[i].to;
            if(dis[t]>dis[x]+w[i])
            {
                dis[t]=dis[x]+w[i];
                if(!vis[t])
                {
                    vis[t]=true;
                    q.push(t);
                    num[t]++;
                    if(num[t]>n) return true;
                }
            }
        }
    }
    return false;
}
int pd()
{
    for(int i=1;i<=n;i++)
     if(spfa(i)) return true;
    return false;
}
int main()
{
    freopen("sugar.in","r",stdin);
    freopen("sugra.out","w",stdout);
    n=read(),m=read();
    for(int i=1;i<=n;i++) c[i]=read();
    for(int i=1;i<=m;i++)
    {
        x=read(),y=read(),z=read();
        add(x,y,z);
    }
    l=0,r=1000000;
    while(r-l>0.00000001)
    {
        mid=(l+r)/2;
        for(int i=1;i<=tot;i++)
        {
            int t=edge[i].to;
            w[i]=(double)mid*edge[i].dis-c[t];
        }
        if(pd())
        {
            ans=mid;
            l=mid;
        }
        else r=mid;
    }
    printf("%.2lf",ans);
    return 0;
}
bfs的spfa(洛谷70)

思路:

奶牛們從起點出發然後在回到起點,也就是說奶牛走過的路徑為一個環,在奶牛走的這個環中ans=所有的樂趣數/路上消耗的所有的時間。

我們將上面的式子進行變形,可以得到路上消耗的所有時間*ans=所有的樂趣數。——>路上消耗的所有時間*ans-所有的樂趣數=0;

然後我們在進行二分答案,處理出ans,然後對於每一個ans跑n個spfa,判斷是否存在負環,如果存在負環就說明當前方案不是最佳答案(存在負環條件:當前點入隊次數大於n,當然這種情況是當我們用bfs的spfa時),讓我們用dfs的spfa時,我們用一個bool變量表示這個數有沒有被訪問過,如果被訪問過,說明他出現了負環直接結束循環。我們的ans還能有更大的解,即當路上消耗的所有的時間*ans-所有的樂趣數<0時我們的ans不是當前最優解繼續更新最優解

註意:二分結束的條件為r-l>0.000001,否則會爆long long

當然你會發現我們會TLE既然這樣我們就寫dfs的spfa判負環,在這之前我有一篇博客講過這種寫法http://www.cnblogs.com/z360/p/6883351.html

技術分享
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 51000
using namespace std;
bool vis[N];
int n,m,x,y,z,tot;
int c[N],num[N],head[N];
double ans,mid,l,r,w[N],dis[N];
struct Edge
{
    int to,dis,from,next;
}edge[N];
int add(int x,int y,int z)
{
    tot++;
    edge[tot].to=y;
    edge[tot].dis=z;
    edge[tot].next=head[x];
    head[x]=tot;
}
int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1; ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0; ch=getchar();}
    return x*f;
}
int spfa(int x)
{
    vis[x]=true;
    for(int i=head[x];i;i=edge[i].next)
    {
        int t=edge[i].to;
        if(dis[t]>dis[x]+w[i])
        {
            dis[t]=dis[x]+w[i];
            if(vis[t]||spfa(t))
            {
                vis[x]=false;
                return true;
            }  
        }
    }
    vis[x]=false;
    return false;
}
int pd()
{
    for(int i=1;i<=n;i++)
        if(spfa(i)) return true;
    return false;
}
int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;i++) c[i]=read();
    for(int i=1;i<=m;i++)
    {
        x=read(),y=read(),z=read();
        add(x,y,z);
    }
    l=0,r=100005;
    while(r-l>0.0000001)
    {
        mid=(l+r)/2;
        for(int i=1;i<=tot;i++)
        {
            int t=edge[i].to;
            w[i]=(double)mid*edge[i].dis-c[t];
        }
        if(pd())
        {
            ans=mid;
            l=mid;
        }
        else r=mid;
    }
    printf("%.2lf",ans);
    return 0;
}
dfs AC代碼

9.15模擬試題