博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
解题思路
阅读量:6831 次
发布时间:2019-06-26

本文共 4607 字,大约阅读时间需要 15 分钟。

简要记录题解思路

f:battle City

bfs+优先队列

每次入队前进行标记,每次出队都上当前最短的路径

bfs+优先队列似乎就是dijkstra算法 ??

code

char mp[maxm][maxn];int vis[maxm][maxn];//记录是否处理过struct node{    int x,y;    int step;    node(int x_,int y_,int s_):x(x_),y(y_),step(s_){}}; bool operator < (node a,node b){        return a.step>b.step;    }int mv[4][2]={
{-1,0},{1,0},{0,-1},{0,1}};//优先队列int m,n;int bfs(node begin,int endx,int endy){ priority_queue
que; vis[begin.x][begin.y]=1; que.push(begin); while(!que.empty()){ node tmp=que.top(); que.pop(); //printf("db %d %d step %d\n",tmp.x,tmp.y,tmp.step); if(tmp.x==endx&&tmp.y==endy) return tmp.step; int tmpx,tmpy,tmps; for(int i=0;i<4;i++){ tmpx=tmp.x+mv[i][0]; tmpy=tmp.y+mv[i][1]; if(tmpx<0||tmpx>=m||tmpy<0||tmpy>=n||vis[tmpx][tmpy]||mp[tmpx][tmpy]=='S'||mp[tmpx][tmpy]=='R') continue;//依旧可能出现相同坐标都在队列中 else if(mp[tmpx][tmpy]=='B') tmps=tmp.step+2; else tmps=tmp.step+1; node t=node(tmpx,tmpy,tmps); vis[tmpx][tmpy]=1; que.push(t); //else if(mp[tmpx][tmpy]=='B'){node t=node(tmpx,tmpy,tmp.step+2);vis[tmpx][tmpy]=1;que.push(t);} //else if(mp[tmpx][tmpy]=='E'||mp[tmpx][tmpy]=='T'){node t=node(tmpx,tmpy,tmp.step+1);vis[tmpx][tmpy]=1;que.push(t);} } } return -1;//no find}node beg=node(0,0,0);int endx,endy;int main(){ while(scanf("%d %d",&m,&n)&&m!=0){ //CL(mp,0); CL(vis,0); /* while(!que.empty()){ que.pop(); } */ for(int i=0;i

g: 从N个数里找出和为N的倍数

数学题(鸽巢原理)+前缀和

处理前缀和的模N为0和相同的情况

code

void output(int i,int j){    printf("%d\n",j-i);    for(int t=i+1;t<=j;t++){        printf("%d\n",a[t]);    }}int main(){    scanf("%d",&n);        //CL(tag,-1);        bool flag=false;//是否已经找到该组数据答案        for(int i=1;i<=n;i++){            scanf("%d",a+i);            if(flag) continue;            sum[i]=a[i];            sum[i]+=sum[i-1];            int mod=sum[i]%n;            if(mod==0){                output(0,i);                flag=true;                continue;            }            //printf("db %d %d mod %d tag[mod] %d\n",i,sum[i],mod,tag[mod]);            if(tag[mod]==0){                tag[mod]=i;            }            else{                output(tag[mod],i);                flag=true;            }        }        return 0;}

h :判断负环

bellman-ford

bellman-ford算法处理单源最短路(可以有负边),基本操作:

N-1次的松弛,每次松弛时对边<u,v> dis[v]=min(dis[v],dis[u]+cost(u,v))
不优化的复杂度O(NE)

code

struct Edge{    int u,v,w,next;    //Edge(int u_,int v_,int w_):u(u_),v(v_),w(w_) {}}es[maxm];//maybe be not need uint head[maxn];//head[u]链表头,边编号int dis[maxn];//init -1int cnt;void add(int u,int v,int w){    es[cnt].u=u;es[cnt].v=v;es[cnt].w=w;    es[cnt].next=head[u];    head[u]=cnt;    cnt++;}void bellman(int s){    //原点s进行bellmanford算法    CL(dis,0x3f);    dis[s]=0;// dis0    //dis1...dis(n-1)    //dis(n)[j]=min(dis(n-1)[j],dis(n-1)[i]+cost[i][j])    for(int t=1;t<=n-1;t++){        //优化之一如果有一次都没更新则停止        //便利所有边        for(int j=0;j
dis[u]+w) dis[v]=dis[u]+w;//更新 } }}bool check(){ //n-1次后还能更新则存在负环 for(int j=0;j
dis[u]+w) return false; } return true;}int main(){ int t; scanf("%d",&t); while(t--){ scanf("%d %d %d",&n,&m,&W); //初始化 cnt=0; CL(head,-1); int u,v,w; for(int i=0;i

I:正方形(找出N个整点构成的正方形个数)

手写hash+简单几何关系

枚举两点,得到正方形的另外两点,hash检索(注意选模,搜索时时搜索自由区域才停)

注意枚举重复情况(4条边都被枚举遍)

code

const int maxn=100007;struct point{    int x,y;    int count;//标志有效位置}hash[100007];int n;int xx[1005],yy[1005];void tohash(int x,int y){    int pos=(x*x+y*y+x-y)%maxn;    while(hash[pos].count!=0){        pos=(pos+1)%maxn;    }    hash[pos].count=1;    hash[pos].x=x;hash[pos].y=y;}int search(int x,int y){    int pos=(x*x+y*y+x-y)%maxn;    while(hash[pos].count!=0){        if(hash[pos].x==x&&hash[pos].y==y) return 1;        pos=(pos+1)%maxn;    }    //printf("db search pos:%d x %d y %d\n",pos,x,y);    //if(hash[pos].x==x&&hash[pos].y==y) return 1;    return 0;}int main(){    while(scanf("%d",&n)&&n!=0){        CL(hash,0);        int x,y;        for(int i=0;i
>2); } return 0;}

j:container

给出三维整点左边,要将这些区域包裹起来的最小表面积

6n-2m ;n是点的个数,m是相接的面

但没找到原题,无法测试

code

struct cell{    int x,y,z;}cels[maxn];int n;bool checkadj(cell c1,cell c2){    return (abs(c1.x-c1.x)+abs(c1.y-c2.y)+abs(c1.z-c2.z))<=1;//no same}int main(){    int t;    scanf("%d",&t);    while(t--){        scanf("%d",&n);        for(int i=0;i

转载于:https://www.cnblogs.com/fridayfang/p/10420935.html

你可能感兴趣的文章
在IIS上部署你的ASP.NET Core项目
查看>>
整理关于牛人们对图书管理系统领域建模的精彩讨论,以此希望大家学习下别人是如何思考的...
查看>>
三星反口承认智能手机遭遇危机,指望Galaxy 10和可折叠手机突围
查看>>
8051,PIC,AVR和ARM有什么区别?
查看>>
C# 匿名委托、匿名方法、匿名对象、Lambda表达式
查看>>
Zabbix zabbix_server指令(学习笔记二十五)
查看>>
老司机总结下 Android Studio 实用小技巧
查看>>
创建最小的Go docker 镜像
查看>>
浅入分析Linux
查看>>
jenkins 从git拉取代码
查看>>
Nginx 配置详解(学习笔记二)
查看>>
C#使用Xamarin开发可移植移动应用(2.Xamarin.Forms布局,本篇很长,注意)附源码
查看>>
查看安卓APK源码破解
查看>>
解决pycharm启动慢
查看>>
SpringBoot实战(八)之RabbitMQ
查看>>
vue插件开发流程详解-从开发到发布至npm(二)
查看>>
Node.js面试题之2017
查看>>
波兰Zortrax研制LCD光固化3D打印机,比SLA快8倍
查看>>
SpringBoot(五)_表单验证
查看>>
JavaScript权威指南 - 函数
查看>>