码迷,mamicode.com
首页 > 其他好文 > 详细

2019/1/28测试

时间:2019-01-28 21:07:38      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:最小值   its   else   serve   body   相交   复杂度   ext   load   

考得最瓜的一次试,一个题也没A。。

题目 A: 迷宫

 

题目描述

【问题描述】

 

电脑游戏中有许多令人头疼的迷宫,会花费玩家相当多的时间,你通过秘笈获得了游戏迷宫的地图,你希望找到最短的一条走出迷宫的道路,并且想知道一共有多少条最短的道路,但是由于地图非常庞大,所以你不能在短时间找出这些道路,因此,你需要编写一个程序来找出这些最短的道路,并且统计一下一共有多少条这样的道路。

例如,对于下图所示的迷宫:

 

 

 

S

 

X

X

 

 

X

X

 

E

 

 

 

X表示障碍物,不可以通过,S表示迷宫的入口,E表示迷宫的出口。显然,从入口到出口至少需要走6步,而长度为6的道路一共有两条。

 

【输入文件】

 

输入文件maze.in,第一行是一个整数n(1 ≤n ≤ 25),表示迷宫是一个n×n的矩阵。以下n行每行有n个字符来描述地图,“.”表示可以通过,“X”表示不可以通过,“S”表示迷宫的入口,“E”表示迷宫的出口。(注意:所有的字母均为大写)。

 

【输出文件】

 

输出文件maze.out包括两行,第一行包含一个整数,表示从入口到出口走的最短距离。第二行包含一个整数,表示最短路径的条数,答案保证小于231

 

【样例输入】

 

4

...S

.XX.

.XX.

E...

 

【样例输出】

 

6

2

 

一个dp,然而考试是以为是搜索,还写炸了,直接爆零(主要是字符读入炸了,改了后还是有50分的。。

 

正解:用dp[i][j][k]表示第i步走到j,k的方案总数,那么转移方程就很简单了,懒得写直接看代码

 

#include<bits/stdc++.h>
using namespace std;
 
int dirx[]={-1,1,0,0},diry[]={0,0,-1,1};
 
int n,dp[26*26][26][26],sx,sy,ex,ey;
char mp[27][27];
int main(){
    scanf("%d\n",&n);
    for(int i=1;i<=n;i++){
            scanf("%s",mp[i]+1);
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            if(mp[i][j]==S) sx=i,sy=j;
            else if(mp[i][j]==E) ex=i,ey=j;
        }
    dp[0][sx][sy]=1;
    for(int t=1;t<=n*n;t++)
       for(int i=1;i<=n;i++)
           for(int j=1;j<=n;j++){
               if(mp[i][j]==X) continue;
               for(int k=0;k<4;k++){
                   int nx=dirx[k]+i,ny=diry[k]+j;
                   if(nx>n||nx<1||ny>n||ny<1) continue;
                   if(mp[nx][ny]==X) continue;  
                   dp[t][i][j]+=dp[t-1][nx][ny];
                }
           }
    for(int t=1;t<=n*n;t++)
    {
        if(dp[t][ex][ey]) {printf("%d\n%d",t,dp[t][ex][ey]);return 0;
        }
    }
    return 0;
}

 

 

题目 B: 最大数列

题目描述

【问题描述】

有一个N项的数列a1, a2 ... aN (|ai| <=10000, 1 <= i <= N)。S定义为


 技术分享图片

你的任务是求S的值,即为求一个序列的两个不相交连续子序列的最大和。

 

【输入文件】

 

输入文件sequence.in的第一行是一个整数N(2 <= N <= 100000),表示数列的项数。第二行有n个整数,用空格分隔,第i个整数Ai(|Ai| <=10000)是第i位数。

 

【输出文件】

 

输出文件sequence.out包括一行,这一行只包含一个整数,就是S。

 

【样例输入】

 

5

-5 9 -5 11 20

 

【样例输出】

 

40

 

【数据规模】

 

对于30%的数据,保证有n <= 80;

对于70%的数据,保证有n <= 10000;

对于全部的数据,保证有n <= 100000。


这个题也是个dp,要依次枚举断点倒是想到了,但先预处理是真的没考虑,打了个n^2的代码,70fen。。

 

定义一个dpr[i]表示i以后的最优解,dpl[i]表示i以前的最优解,可用前缀和与后缀和来做,最后枚举断点,时间复杂度为O(n)

#include<bits/stdc++.h>
#define maxn 100001
using namespace std;
 
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch>9||ch<0) {if(ch==-) f=-1;ch=getchar();}
    while(ch>=0&&ch<=9) {x=x*10+ch-0;ch=getchar();}
    return x*f;
}
 
int n,a[maxn],sum1[maxn],sum2[maxn],dpl[maxn],dpr[maxn];
 
int main(){
    n=read();
    for(int i=1;i<=n;i++){
        a[i]=read();
    }
    for(int i=1;i<=n;i++) sum1[i]=sum1[i-1]+a[i];
    for(int i=n;i>=1;i--) sum2[i]=sum2[i+1]+a[i];
    int min1=0;dpl[0]=-0x3f3f3f3f;
    for(int i=1;i<n;i++){
        dpl[i]=dpl[i-1];
        dpl[i]=max(dpl[i],sum1[i]-min1);
        min1=min(min1,sum1[i]);
    }
    int min2=0;dpr[n+1]=-0x3f3f3f3f;
    for(int i=n;i>1;i--){
        dpr[i]=dpr[i+1];
        dpr[i]=max(dpr[i],sum2[i]-min2);
        min2=min(min2,sum2[i]);
    }
    int ans=-0x3f3f3f3f;
    for(int k=1;k<n;k++)
    {
        ans=max(ans,dpl[k]+dpr[k+1]);
    }
    printf("%d",ans);
    return 0;
}

 

题目 C: 安装服务器

题目描述

【问题描述】

 

政府计划建立一个大型的服务器中心,为各个城市提供网络服务。每个城市对网络的需求量是不一样的,而需求量越大,对线路的要求也就越高,线路的成本也就越高。因此需要选择合适的地点修建。每个城市用一个二维整数坐标表示,两个点之间的距离定义为水平距离+垂直距离,即a,b两点间距离为D(a,b)=|Xa-Xb|+|Ya-Yb|。对于每个城市,线路的费用为:费用=距离×人口×城市的网络需求程度。总的费用为各个城市的费用的总和。请你找出最适合安装服务器(既总费用最小)的整数坐标(不一定要在城市上)。

 

【输入文件】

 

输入文件server.in第一行有一个正整数N(N ≤ 100000),表示城市的数量。后面的n行每行描述一个城市,每行有四个整数x,y,p,k分别表示城市的坐标,人口数,以及网络需求程度。(0 < x, y < 2^31;p≤600, k ≤30)

 

【输出文件】

 

输出文件server.out包含一行。在这一行中,应当包含两个整数x,y表示最优解的坐标,如果有多个最优解,那么输出x最小的,如果有x相同,那么输出y最小的。

 

【样例输入】

 

5

2 3 5 3

2 1 100 30

2 2 1 1

3 2 7 6

1 1 4 30

 

【样例输出】

 

2 1

 

【数据规模】

 

对于30%的数据,保证有N <= 500,x, y <= 100;

对于50%的数据,保证有N <= 5000;

对于全部的数据,保证有N <= 100000。

 

一个很经典的带权中位数的题,x与y是无关的,所以只需分别算x与y的最小值就行

 

#include<bits/stdc++.h>
#define maxn 100001
using namespace std;
 
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch>‘9‘||ch<‘0‘) {if(ch==‘-‘) f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘) {x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
 
int n,ansx,ansy,tot;
 
struct node{
    int x,y,qz;
}a[maxn];
 
bool cmp1(node a,node b){
    return a.x<b.x;
}
 
bool cmp2(node a,node b){
    return a.y<b.y;
}
 
int main(){
    n=read();
    for(int i=1;i<=n;i++) a[i].x=read(),a[i].y=read(),a[i].qz=read()*read(),tot+=a[i].qz;
    sort(a+1,a+1+n,cmp1);
    int sum=0;
    for(int i=1;i<=n;i++){
        sum+=a[i].qz;
        if(sum*2>=tot){
            ansx=a[i].x;break;
        }
    }
    sort(a+1,a+1+n,cmp2);
    sum=0;
    for(int i=1;i<=n;i++){
        sum+=a[i].qz;
        if(sum*2>=tot){
            ansy=a[i].y;break;
        }
    }
    printf("%d %d",ansx,ansy);
    return 0;
}

2019/1/28测试

标签:最小值   its   else   serve   body   相交   复杂度   ext   load   

原文地址:https://www.cnblogs.com/plysc/p/10331559.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!