2014年中南大学研究生复试机试题(字符串、基础dp、最短路)

A、B、C题很简单。

D、最大连续子序列

思路:

求最大连续子序列的值以及左右端点。

那么我们记录连续和值为s,最值为maxx,只有maxx改变时才改变左右端点,考虑记录l,r,即当前的区间端点。

那么当s<0时,那么我们直接更新l=r=i,当s>0,s+a[i],同时更新r的值。

代码:

#include
#include
#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
#include
#include
#include
#include
#include 
#include
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
#include
#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
#include
#include
#include
#include
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]

 

你可能感兴趣的:(考研机试)