【NOIP2012模拟10.20】路径数
时间:2019-09-28
本文章向大家介绍【NOIP2012模拟10.20】路径数,主要包括【NOIP2012模拟10.20】路径数使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
路径数
题目描述
Euphemia到一个\(N*N\)的药草田里采药,她从左上角的格子田(第一行,第一列)出发,要到达右下角(第\(N\)行,第\(N\)列)的格子田,每次她可以走到与当前格子有边相邻的格子去,但她不会走已经走过的格子,而且出于对美的要求,她走过的路径是关于 左下-右上 对角线对称的。由于地势不同,在每个格子田采药都会有一个疲劳度\(T_{i,j}\),Euphemia想知道:有多少条合法路径,可以使得她采药的疲劳度最小。
输入格式:
多组数据。
每组数据第一行一个整数\(N\),接下来\(N\)行,每行$N4个非零数字(\(1,2,3...9\)中一个),表示格子田的疲劳度。
当\(N=0\),输入结束。
输出格式:
对于每组数据,输出一个整数表示答案,答案%1000000009。
样例输入:
2 1 1 1 1 3 1 1 1 1 1 1 2 1 1 0
样例输出:
2 3
数据范围:
对于\(20%\)的数据满足\(N<=5\)。
对于另外\(20%\)的数据满足\(N<=40\)。
对于\(100%\)的数据满足\(N<=100\),不超过\(50\)组数据。
时间限制:
1S
空间限制:
256M
提示:
remove!!!
题解
根据题意可知这是一道图论题。
求最短路径的方案数。
因为她走过的路径是关于 左下-右上 对角线对称的所以我们可以把这个矩阵沿 左下-右上 对角线“对折”下来。
接下来在剩下的“三角形图”上跑dijstra求最短路,并且松弛的时候记录一下方案数就好了。
最后在对角线上统计一下最短路的方案数。
dijstra加上堆优化,时间复杂度是\((N^3)\)(节点数为\(N^2\))。
上代码:
#include<bits/stdc++.h>
#include<queue>
#define mod 1000000009
using namespace std;
int n;
int a[109][109];
int dis[109][109],s[109][109];
bool k[109][109];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
void dij(int x,int y){
priority_queue< pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > pp;
dis[1][1]=a[1][1];
s[1][1]=1;
pp.push(make_pair(dis[x][y],x*n+y-1));
while(!pp.empty()){
pair<int,int> u=pp.top();
pp.pop();
int y=u.second%n+1,x=u.second/n;
// printf("*%d %d*\n",x,y);
if(k[x][y]) continue;
k[x][y]=1;
for(int j=0;j<4;j++){
int xx=x+dir[j][0],yy=y+dir[j][1];
if(xx<1 || yy<1 || xx+yy>n+1 || k[xx][yy]) continue;
// printf("!%d %d!\n",xx,yy);
if(dis[xx][yy]==-1 || dis[xx][yy]>dis[x][y]+a[xx][yy]){
dis[xx][yy]=dis[x][y]+a[xx][yy];
s[xx][yy]=s[x][y];
pp.push(make_pair(dis[xx][yy],xx*n+yy-1));
}
else if(dis[xx][yy]==dis[x][y]+a[xx][yy]) s[xx][yy]+=s[x][y];
}
}
}
int main() {
while(1){
scanf("%d",&n);
if(n==0) break;
memset(dis,-1,sizeof(dis));
memset(s,0,sizeof(s));
memset(a,0,sizeof(a));
memset(k,0,sizeof(k));
for(int j=1;j<=n;j++)
for(int i=1;i<=n;i++)
scanf("%d",&a[j][i]);
for(int j=1;j<=n;j++)
for(int i=n-j+2;i<=n;i++)
a[n-i+1][n-j+1]+=a[j][i];
dij(1,1);
int mn=-1,ss;
for(int j=1;j<=n;j++){
// printf("**%d %d %d**\n",j,dis[j][n-j+1],s[j][n-j+1]);
if(mn==-1 || mn>dis[j][n-j+1]){
mn=dis[j][n-j+1];
ss=s[j][n-j+1];
}
else if(mn==dis[j][n-j+1]) ss+=s[j][n-j+1];
}
printf("%d\n",ss);
}
return 0;
}
原文地址:https://www.cnblogs.com/linjiale/p/11603189.html
- JavaScript引用类型之Array数组的栈方法与队列方法
- ExtJs学习笔记(14)_Column布局
- 高级盲注—floor,rand,group by报错注入
- 刷脸注册、试装、支付……仅靠一张脸就能买买买的时尚店开业了
- JavaScript引用类型之Array数组之强大的splice()方法
- Linux快速入门03-系统管理
- JavaScript引用类型之Array数组的concat()和push()方法的区别
- JavaScript引用类型之Array数组的排序方法
- Linux快速入门02-文件系统管理
- JavaScript引用类型之Array数组的toString()和valueof()方法的区别
- Linux快速入门04-扩展知识
- JavaScript引用类型之Array数组的拼接方法-concat()和截取方法-slice()
- JavaScript引用类型之Array数组的拼接方法-concat()和截取方法-slice()
- 比特币在2017全球新闻谷歌搜索中排名第二,韩国政府聚焦比特币市场诈骗和假冒交易所
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法