20101010 exam

2018 10.10 exam 解題報告

T1:LOJ #10078 新年好

題目描述(原題來自:CQOI 2005):

重慶城裏有n個車站,m 條雙向公路鏈接其中的某些車站。每兩個車站最多用一條公路鏈接,從任何一個車站出發均可以通過一條或者多條公路到達其餘車站,但不一樣的路徑須要花費的時間可能不一樣。在一條路徑上花費的時間等於路徑上全部公路須要的時間之和。ios

佳佳的家在車站1,他有五個親戚,分別住在車站 a,b,c,d,e。過年了,他須要從本身的家出發,拜訪每一個親戚(順序任意),給他們送去節日的祝福。怎樣走,才須要最少的時間?優化

輸入格式:

第一行:n,m爲車站數目和公路的數目。spa

第二行:a,b,c,d,e爲五個親戚所在車站編號。code

如下 m 行,每行三個整數 x,y,t,爲公路鏈接的兩個車站編號和時間。blog

輸出格式:

輸出僅一行,包含一個整數 T,爲最少的總時間。ci

樣例輸入:

6 6
2 3 4 5 6
1 2 8
2 3 3
3 4 4
4 5 5
5 6 2
1 6 7get

樣例輸出:

21string

數據範圍與提示:

對於所有數據,1≤n≤50000,1≤m≤1e5,1<a,b,c,d,e≤n,1≤x,y≤n,1≤t≤100.it

思路:

對於考場上我咋想的。。。我已經不想說啥了,我個SB。。。原本想寫單源最短路(dij+堆優化),,無奈,搞不出來,就寫了個鄰接表+spfa,雖然亂搞出樣例,可是成功GG。

代碼實現:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=5e4+10;
const int inf=0x7ffffff;

struct node{
    int v,nxt,val;
}e[N<<2];

int dis[7][N],a[10],head[N],f[50],Vis[N],vis[N];
int js,n,m,ans=inf;

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

inline void add_edge(int u,int v,int val) {
    e[++js].v=v,e[js].val=val;
    e[js].nxt=head[u],head[u]=js;
} 

inline void spfa(int s,int t) {
    memset(vis,0,sizeof(vis));
    queue<int>q;
    q.push(s);
    vis[s]=1,dis[t][s]=0;
    while (!q.empty()) {
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];i;i=e[i].nxt) {
            int v=e[i].v;
            if(dis[t][v]>dis[t][u]+e[i].val) {
                dis[t][v]=dis[t][u]+e[i].val;
                if(!vis[v]) {
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
}

inline void dfs(int t) {
    if(t==6) {
        int res=0;
        for(int i=1;i<6;++i) res+=dis[f[i]][a[f[i+1]]];
        ans=min(ans,res);
        return ;
    }
    for(int i=2;i<=6;++i) {
        if(!Vis[i]) {
            Vis[i]=1,f[t+1]=i;
            dfs(t+1),Vis[i]=0;
        }
    }
}

int main() {
    n=read(),m=read();
    for(int i=2;i<=6;++i) a[i]=read();
    for(int i=1;i<=m;++i) {
        int u=read(),v=read(),val=read();
        add_edge(u,v,val),add_edge(v,u,val); 
    }
    memset(dis,0x3f,sizeof(dis));
    a[1]=f[1]=1;
    for(int i=1;i<=6;++i) spfa(a[i],i);
    dfs(1);
    printf("%d",ans);
    return 0;
}

T2: LOJ #10220 Fibonacci 第 n 項

題目描述

你們都知道 Fibonacci 數列吧,
如今問題很簡單,輸入 n 和 m ,求

輸入格式

輸入 n,m。

輸出格式

輸出

樣例輸入

5 1000

樣例輸出

5

數據範圍與提示

對於 100% 的數據, 1≤n≤2×1e09,1≤m≤1e9+10.

思路:

直接上板子QWQ

代碼實現:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int n,m;

struct note{
    int a[2][2];
}e,a;

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

inline void mul(note A,note &B) {
    note C;
    C.a[0][0]=C.a[0][1]=C.a[1][0]=C.a[1][1]=0;
    for(int i=0;i<=1;i++)
        for(int j=0;j<=1;j++)
            for(int k=0;k<=1;k++)
                C.a[i][j]=(1ll*A.a[i][k]*B.a[k][j]+1ll*C.a[i][j])%m;
    for(int i=0;i<=1;i++)
        for(int j=0;j<=1;j++)
            B.a[i][j]=C.a[i][j];
}

inline void gg(int y) {
    for(;y;y>>=1,mul(e,e)) 
    if(y&1) mul(e,a);
}

int main(){
    n=read(),m=read();
    a.a[0][0]=a.a[1][0]=1;e.a[0][0]=0,e.a[0][1]=e.a[1][0]=e.a[1][1]=1;
    if(n==1) printf("%d\n",1%m);
    gg(n-2);
    printf("%d",a.a[1][0]);
    return 0;
}

T3: LOJ #10178 旅行問題

題目描述

John 打算駕駛一輛汽車周遊一個環形公路。公路上總共有 nnn 車站,每站都有若干升汽油(有的站可能油量爲零),每升油可讓汽車行駛一公里。John 必須從某個車站出發,一直按順時針(或逆時針)方向走遍全部的車站,並回到起點。在一開始的時候,汽車內油量爲零,John 每到一個車站就把該站全部的油都帶上(起點站亦是如此),行駛過程當中不能出現沒有油的狀況。

任務:判斷以每一個車站爲起點可否按條件成功周遊一週。

輸入格式

第一行是一個整數 n,表示環形公路上的車站數;

接下來 n 行,每行兩個整數 p_i,d_i ,分別表示表示第 i 號車站的存油量和第 i 號車站到下一站的距離。

輸出格式

輸出共 n 行,若是從第 i 號車站出發,一直按順時針(或逆時針)方向行駛,可以成功周遊一圈,則在第 i 行輸出 TAK,不然輸出 NIE。

樣例輸入

5
3 1
1 2
5 2
0 1
5 4

樣例輸出

TAK
NIE
TAK
NIE
TAK

數據範圍與提示

對於所有數據,3≤n≤1e6,0≤pi≤2×1e9,0<di≤2×1e9

思路:

DP ? QWQ,表示不造,咋辦?模擬。。。完了後期模着模着,完全凌亂了(qwq....我把本身寫亂了),樣例太水了,輕鬆水過,But...爲毛一對拍就錯了,好吧,因而就開始了花式亂搞之路,在偏離的道路上一去不復返...(調不出來,qaq,後期都沒有動力了╮(╯▽╰)╭)

代碼實現:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=2e6+10;
const int inf=0x7ffff;

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

int n,m;
ll ans[N],pos[N],f[N],sum[N],p[N],d[N];

deque <int> q;

inline void check() {
    for(int i=1;i<=m;++i) sum[i]=sum[i-1]+f[i];
    for(int i=1;i<=m;++i){
        while(!q.empty() && sum[q.back()]>sum[i]) q.pop_back();
        q.push_back(i);
        while(q.front()<i-n+1) q.pop_front();
        if(i>=n && sum[q.front()]-sum[i-n]>=0) ans[pos[i-n+1]]|=1;
    }
}

int main() {
    n=read();
    m=n<<1;
    for(int i=1;i<=n;++i) p[i]=read(),d[i]=read();
    for(int i=1;i<=n;++i) f[i]=f[i+n]=p[i]-d[i],pos[i]=pos[i+n]=i;
    check();
    int js=1;
    f[js]=f[js+n]=p[1]-d[n];
    pos[js]=pos[js+n]=1;
    for(int i=n;i>=2;--i) {
        js++;
        f[js]=f[js+n]=p[i]-d[i-1];
        pos[js]=pos[js+n]=i;
    }
    check();
    for(int i=1;i<=n;++i) {
        if(ans[i]) printf("TAK\n");
        else printf("NIE\n");
    }
    return 0;
}
相關文章
相關標籤/搜索