二维数组的前缀和:
class NumMatrix {
public:
int n,m;
vector<vector<int> >sum;
NumMatrix(vector<vector<int>>& matrix) {
n=matrix.size(),m=matrix[0].size();
sum=vector<vector<int> >(n,vector<int>(m,0));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
sum[i][j]=matrix[i][j];
if(i-1>=0){
sum[i][j]+=sum[i-1][j];
}
if(j-1>=0){
sum[i][j]+=sum[i][j-1];
}
if(i-1>=0&&j-1>=0){
sum[i][j]-=sum[i-1][j-1];
}
}
}
}
int sumRegion(int row1, int col1, int row2, int col2) {
int ans=sum[row2][col2];
if(row1-1>=0){
ans-=sum[row1-1][col2];
}
if(col1-1>=0){
ans-=sum[row2][col1-1];
}
if(row1-1>=0&&col1-1>=0){
ans+=sum[row1-1][col1-1];
}
return ans;
}
};
广搜走地图
- 连通性
- 最少步数
- 按层遍历,比较暴力
启发式搜索算法
- 离起点有多远(按层遍历)
- 终点有多远
- 可以采用欧式距离,采用优先队列
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
struct node{
int x,y,step;
double h;
bool operator<(const node&b)const{
return step+h>b.step+b.h;
}
};
int n,m,sx,sy,ex,ey,cnt;
int dir[8][2]={0,1,1,0,0,-1,-1,0,1,1,1,-1,-1,1,-1,-1};
char mmap[105][105];
void func(int x,int y){
if(mmap[x][y]=='S') return ;
mmap[x][y]='o';
func(fx[x][y],fy[x][y]);
}
double dis(int x,int y){
int t1=x-ex,t2=y-ey;
return sqrt(t1*t1 + t2*t2);
}
void p(int cnt){
cout<<"-----------"<<cnt<<"--------------"<<endl;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cout<<mmap[i][j];
if(mmap[i][j]=='x'){
mmap[i][j]='~';
}
}
cout<<endl;
}
cout<<"-------------------------------------------"<<endl;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(mmap[i][j]=='S'){
sx=i,sy=j;
}
if(mmap[i][j]=='T'){
ex=i,ey=j;
}
}
}
priority_queue<node>que;
que.push((node){sx,sy,0,dis(sx,sy)});
while(!que.empty()){
node temp=que.top();
que.pop();
for(int i=0;i<8;i++){
int x=temp.x+dir[i][0];
int y=temp.y+dir[i][1];
if(mmap[x][y]=='T'){
func(temp.x,temp.y);
p(cnt);
cout<<temp.step+1<<endl;
return 0;
}
if(mmap[x][y]=='.'){
mmap[x][y]='x';
que.push((node){x,y,temp.step+1,dis(x,y)});
cnt++;
if(cnt%5==0){
p(cnt);
}
}
}
}
return 0;
}
LRU最近缓存系统:
class LRUCache {
public:
struct node{
int key,val;
node*front,*back;
node(){
key=-1,val=-1;
front=back=nullptr;
}
node(int k,int v){
key=k,val=v;
front=back=nullptr;
}
};
unordered_map<int,node*>m;
node*l,*r;
int mmax,now;
// int size,m_capacity;
LRUCache(int capacity) {
mmax=capacity,now=0;
l=new node();
r=new node();
l->back=r;
r->front=l;
}
int get(int key) {
if(m.count(key)){
push_frt(m[key]);
return m[key]->val;
}
return -1;
}
void push_frt(node*p){
if(p->front!=nullptr){
p->front->back=p->back;
p->back->front=p->front;
}
p->back=l->back;
p->front=l;
l->back->front=p;
l->back=p;
}
void del_back(){
node*p=r->front;
m.erase(p->key);
p->front->back=r;
r->front=p->front;
delete p;
}
void put(int key, int value) {
node*p;
if(m.count(key)==0){
p=new node(key,value);
m[key]=p;
now++;
}else{
p=m[key];
p->val=value;
}
push_frt(p);
if(now>mmax){
now--;
del_back();
}
}
};
复习:递员送信问题
有一个邮递员要送东西,邮局在节点 11。他总共要送 n-1n−1 样东西,其目的地分别是节点 22 到节点 nn。由于这个城市的交通比较繁忙,因此所有的道路都是单行的,共有 mm 条道路。这个邮递员每次只能带一样东西,并且运送每件物品过后必须返回邮局。求送完这 n-1n−1 样东西并且最终回到邮局最少需要的时间。
输入格式
第一行包括两个整数,nn 和 mm,表示城市的节点数量和道路数量。
第二行到第 (m+1)(m+1) 行,每行三个整数,u,v,wu,v,w,表示从 uu 到 vv 有一条通过时间为 ww 的道路。
输出格式
输出仅一行,包含一个整数,为最少需要的时间。
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
struct edge{
int e,v,next;
};
edge edg[2][100005];
int n,m,ans[2][100005],head[2][100005],mark[100005];
void add_edg(int cnt,int ind,int s,int e,int v){
edg[cnt][ind].e=e;
edg[cnt][ind].v=v;
edg[cnt][ind].next=head[cnt][s];
head[cnt][s]=ind;
}
void func(int cnt){
memset(mark,0,sizeof(mark));
queue<int>que;
que.push(1);
ans[cnt][1]=0;
mark[1]=1;
while(!que.empty()){
int temp=que.front();
que.pop();
mark[temp]=0;
for(int i=head[cnt][temp];i!=-1;i=edg[cnt][i].next){
int e=edg[cnt][i].e,v=edg[cnt][i].v;
if(ans[cnt][e]>ans[cnt][temp]+v){
ans[cnt][e]=ans[cnt][temp]+v;
if(mark[e]==0){
mark[e]=1;
que.push(e);
}
}
}
}
}
int main(){
memset(head,-1,sizeof(head));
memset(ans,0x3F,sizeof(ans));
cin>>n>>m;
for(int i=0;i<m;i++){
int a,b,c;
cin>>a>>b>>c;
add_edg(0,i,a,b,c);
add_edg(1,i,b,a,c);
}
func(0);
func(1);
long long sum=0;
for(int i=2;i<=n;i++){
sum+=ans[0][i]+ans[1][i];
}
cout<<sum<<endl;
return 0;
}