2014年中南大學研究生複試機試題(字符串、基礎dp、最短路)

A、B、C題很簡單。

D、最大連續子序列

思路:

求最大連續子序列的值以及左右端點。

那麼我們記錄連續和值爲s,最值爲maxx,只有maxx改變時才改變左右端點,考慮記錄l,r,即當前的區間端點。

那麼當s<0時,那麼我們直接更新l=r=i,當s>0,s+a[i],同時更新r的值。

代碼:

#include<iostream>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#include<string.h>
#include<queue>
#include<stack>
#include<cstdio>
#include<cmath>
#include <stdlib.h>
#include<stack>
using namespace std;
const int maxn=100000+10;
#define mod 1000000007
#define INF 0x3f3f3f3f
int dx[]= {-1,1,0,0};
int dy[]= {0,0,-1,1};
int a[maxn];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int ansl=0,ansr=0,ans=0;
        int l=0,r=0;
        rep(i,0,n-1)scanf("%d",&a[i]);
        int s=0;
        int maxx=-999999;
        rep(i,0,n-1)
        {
            if(s<0)
            {
                s=a[i];
                l=i;
                r=i;
            }else
            {
                r=i;
                s+=a[i];
            }
            if(s>maxx)
            {
                maxx=s;
                ansl=l;
                ansr=r;
                ans=maxx;
            }
        }
        if(ans<0)
        {
            ansl=0;
            ansr=0;
            ans=0;
        }
        printf("%d %d %d\n",ans,ansl,ansr);
    }
}

E、安全路徑

思路:

在更新dis數組時和迪傑斯特拉算法的思想一樣,由原來的+變成了*,最短路變成了最長路,貪心原則改爲先取長的即可。

代碼:

#include<iostream>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#include<string.h>
#include<queue>
#include<stack>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=1000+6;
#define mod 1000000007
#define INF 0x3f3f3f3f
int dx[]= {-1,1,0,0};
int dy[]= {0,0,-1,1};
struct edges
{
    int to;
    int next;
    double v;
} edge[maxn*maxn];
int cnt;
int head[maxn*2];
void add(int u,int v,double w)
{
    edge[++cnt].to=v;
    edge[cnt].next=head[u];
    edge[cnt].v=w;
    head[u]=cnt;
}
double dis[maxn];
bool vis[maxn];
int n;
double maxx;
bool dir(int s,int t)
{
    rep(i,1,maxn-1)dis[i]=0;
    rep(i,1,maxn-1)vis[i]=0;
    dis[s]=1;
    for(int i=1; i<=n; i++)
    {
        double minn=-INF;
        int tmp=-1;
        rep(j,1,n)
        {
            if(vis[j])
                continue;
            if(dis[j]>minn)
            {
                minn=dis[j];
                tmp=j;
            }
        }
        vis[tmp]=1;
        for(int j=head[tmp]; j; j=edge[j].next)
        {
            int v=edge[j].to;
            double w=edge[j].v;
            if(w==0)
                continue;
            if(dis[v]<dis[tmp]*w)
            {
                dis[v]=dis[tmp]*w;
            }
        }
    }
    return dis[t];
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        cnt=0;
        memset(head,0,sizeof(head));
        rep(i,1,n)
        {
            rep(j,1,n)
            {
                double x;
                scanf("%lf",&x);
                add(i,j,x);
            }
        }
        int m;
        scanf("%d",&m);
        while(m--)
        {
            maxx=-1;
            int u,v;
            scanf("%d %d",&u,&v);
            bool flag=dir(u,v);
            if(!flag)
                printf("What a pity!\n");
            else
                printf("%.3lf\n",dis[v]);
        }
    }
    return 0;
}
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章