1012

题意:

n*m大小的矩形,起点在矩形的左上角, 终点在右下角,里面一个小矩形代表一个街区(block)。每个小矩形的边长都是2520, 小矩形的边有一个速度限制,范围是0~9, 如果是0表示这条边不能行驶。 数字表示边的限速, 符号表示这条路方向

思路:Dijkstra算法求出最短路径,主要是注意输入

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<utility>
using namespace std;  

typedef pair<int,int>pii;
const int INF = 0x7fffffff;
const int VN = 445;
const int EN = VN*VN/2;  

struct Edge{
    int v, next, w;
}E[EN];  

int n;
int m;
int vn;
int size;
int head[VN];
int d[VN];  

void addEdge(int u,int v,int w){
    E[size].v=v;
    E[size].w=w;
    E[size].next=head[u];
    head[u]=size++;
}
void init(){
    vn=(m+1)*(n+1);
    size=0;
    memset(head, -1, sizeof(head));
}  

void Dijkstra(int src){
    for(int i=1; i<=vn; ++i)d[i]=INF;
    d[src]=0;
    priority_queue<pii,vector<pii>,greater<pii> >q;
    q.push(make_pair(d[src],src));
    while(!q.empty()){
        pii x = q.top(); q.pop();
        int u=x.second;
        if(d[u]!=x.first)continue;
        for(int e=head[u]; e!=-1; e=E[e].next){
            int tmp=d[u]+E[e].w;
            if(d[E[e].v] > tmp){
                d[E[e].v] = tmp;
                q.push(make_pair(tmp,E[e].v));
            }
        }
    }
}  

int main(){
    char str[100];
    int u,v,w;
    while(~scanf("%d%d%*c",&n,&m)&&n+m){
        // input
        init();
        for(int i=1; i<=n*2+1; ++i){
            gets(str);
            int len=strlen(str);
            if(i&1){
                for(int j=0,k=1; j<len; j+=4,++k){
                    u=(m+1)*(i/2)+k;
                    w = str[j]-‘0‘;
                    if(w==0)continue;
                    if(str[j+2]==‘*‘){
                        addEdge(u,u+1,2520/w);
                        addEdge(u+1,u,2520/w);
                    }
                    else if(str[j+2]==‘<‘){
                        addEdge(u+1,u,2520/w);
                    }
                    else{
                        addEdge(u,u+1,2520/w);
                    }
                }
            }
            else{
                for(int j=0,k=1; j<len; j+=4,++k){
                    u = (m+1)*(i/2-1)+k;
                    w = str[j]-‘0‘;
                    if(w==0) continue;
                    if(str[j+2]==‘*‘){
                        addEdge(u, u+m+1, 2520/w);
                        addEdge(u+m+1, u, 2520/w);
                    }
                    else if(str[j+2]==‘v‘){
                        addEdge(u, u+m+1, 2520/w);
                    }
                    else if(str[j+2]==‘^‘){
                        addEdge(u+m+1, u, 2520/w);
                    }
                }
            }
        }
        Dijkstra(1);
        if(d[vn]!=INF) printf("%d blips\n", d[vn]);
        else puts("Holiday");
    }
    return 0;
}  
时间: 2024-10-24 19:02:41

1012的相关文章

HDU 1012 u Calculate e【暴力打表,水】

u Calculate e Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 46844    Accepted Submission(s): 21489 Problem Description A simple mathematical formula for e is where n is allowed to go to infini

BZOJ 1012 [JSOI2008]最大数maxnumber

怎么做都可以题..可以用线段树..可以用平衡树..反正有不少方法 个人比较滋磁单调队列+二分查找的写法,常数小代码少易理解. 具体思路就是维护一个单调不上升的单调队列,然后查询就在这个单调队列中二分查找就好啦~ //这道题,可以算是单调队列的一个妙用了 //当然,做法有很多,可以用线段树.平衡树.树状数组等,其中单调队列最巧妙且最简单 //为什么这道题可以使用单调队列呢? //(即队列中存储的序列必定是下标单调并且数值单调) //如果每个结点没有下标优势(早点入队)也没有数值优势(更大),那么显

【单调栈】Bzoj 1012: 最大数maxnumber

1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 6255  Solved: 2676[Submit][Status][Discuss] Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度. 2. 插入操作.语法:A n 功能:将n加上t,其中t是最近一次

水题/hdu 1012 u Calculate e

题意 求n=0~9时的sigma(1/n!) 分析 因为刚学c++ 所以对浮点操作还是很不熟练,正好来了这么一道题 Accepted Code 1 /* 2 PROBLEM:hdu 1012 3 AUTHER:Nicole Lam 4 MEMO:水题 5 */ 6 #include<iostream> 7 #include<iomanip> 8 using namespace std; 9 double a[10]; 10 int main() 11 { 12 cout<&l

hdu 1012:u Calculate e(数学题,水题)

u Calculate e Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 28686    Accepted Submission(s): 12762 Problem Description A simple mathematical formula for e iswhere n is allowed to go to infinit

1012. 变换密码

1012. 变换密码 (Standard IO) 时间限制: 1000 ms  空间限制: 262144 KB  具体限制 题目描述 一密码变换规则如下:一个正整数对应一个字符:如果该数模123的值在97-122范围,变换为ASCII为该余数对应的小写字符:如果变换不了小写字符,将该数模91,若余数在65-90范围,变换为ASCII为该余数对应的大写字符:如果变换不了大小写字符,变换为“*”.输入一个正整数,输出变换后的字符. 输入 输入一个正整数n(1<=n<=1000)表示原始密码. 输出

BZOJ 1012 线段树或单调队列

1012: [JSOI2008]最大数maxnumber 题意:两种操作:1.查询当前数列中末尾L个数中的最大的数:2.当前数列末尾插入一个数. tags:水题 线段树 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define FF(i,a,b) for (int i=a;i<=b;i++) #define F(i

bzoj-1012 1012: [JSOI2008]最大数maxnumber(线段树)

题目链接: 1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MB Description 现在请求你维护一个数列,要求提供以下两种操作:1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度.2. 插入操作.语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得

PAT 1012

1012. The Best Rank (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue To evaluate the performance of our first year CS majored students, we consider their grades of three courses only: C - C Programming Language, M - Mathematic

1012 最大公约数和最小公倍数问题

http://codevs.cn/problem/1012/ 题目描述 Description 输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数 条件:  1.P,Q是正整数 2.要求P,Q以x0为最大公约数,以y0为最小公倍数. 试求:满足条件的所有可能的两个正整数的个数. 输入描述 Input Description 二个正整数x0,y0 输出描述 Output Description 满足条件的所有可能的两个正