图论大赛的简单分析

总体分析:

第一道题:一个字!水!!,只不过看数据的话那个第五个测评点会非常大,需要一个并查集剪枝维护才能A,但是考试的时候过了样例,就没考虑那么多,一共6个点,5个点开考20分钟秒过……

第二道题:四个字!半水不水!!,做题时发现呵呵呵呵……(苦笑)把DFS全写完,样例过了,但是乍得一看数据范围,一下子就懵了。最后没有改用BFS,A过3个点,另外两个点栈溢出,开考50分钟后写完。

第三道题:如果你知道样例,基本上可以放弃了。可惜我用30分钟写了一个FLOYD无敌大暴力,五层循环把样例A过了,结果一个点结果错误,另九个点时间超限……(早知道我不写了)

第四道题:剩下20分钟,呵呵呵,开手速吧……15分钟竟然写过了!?没有!如果单单是有传送门的话我就A了,但是输入要求非常莫名其妙,竟然不输入行数和列数?还有折叠空间?一生气,果断卡测评机。

我过了8个点,160分,感觉自己要跪了,结果问问发现200+的有三个我们学校的大神,然后140+的有7个,其中2个新初二的,2个新初一的,还有一个新高一的,一个新初三的。80+的有四个大犇,剩下的14+个全是0分、20分、40分左右的。题很水啊~~是不是失手了??想我这样的弱鸡都能对8个点,醉了……

下面来一些具体分析~~

敌人

考试做法:跟团伙貌似没有任何区别,单纯并查集就有5个点了。

正解做法:用SIZE数组维护树的规模,其它没难度……

【代码】

#include<iostream>
using namespace std;
int n,m,a,b,pre[300101],ans;
int tmp[300101];
bool vis[300101];
int ch;
int find(int x)//找i节点的指针指向的节点编号
{
    int t=x;
    if(pre[t]!=t) pre[t]=find(pre[t]);
    return pre[t];
}
void join(int x,int y)//连边
{
    int tx=find(x),ty=find(y);
    pre[tx]=ty;
    return;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) pre[i]=i;
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&ch);
        if(ch==1)
        {
            scanf("%d%d",&a,&b);
            if(find(a)==find(b)) printf("Y\n");//如果指针一样那么就是朋友
            else
            {
                printf("N\n");//输出不是
                if(!tmp[a]) tmp[a]=b;//逆向储存
                else join(tmp[a],b);
                if(!tmp[b]) tmp[b]=a;
                else join(tmp[b],a);
            }
        }
        else
        {
            scanf("%d",&a);
            for(int j=1;j<=n;j++) if(find(a)==find(j)&&a!=j) ans++;//这里需要优化,否则时间超限
            printf("%d\n",ans);
            ans=0;
        }
    }
}

国际象棋

没难度,只不过一定要用BFS!!

我的代码:

#include<iostream>
#include<cstring>
using namespace std;
inline int read(){
    int x=0,sig=1;char ch=getchar();
    while(!isdigit(ch)){if(ch==‘-‘)sig=-1;ch=getchar();}
    while(isdigit(ch))x=10*x+ch-‘0‘,ch=getchar();
    return x*=sig;
}
inline void write(int x){
    if(x==0){putchar(‘0‘);return;}if(x<0)putchar(‘-‘),x=-x;
    int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    for(int i=len-1;i>=0;i--)putchar(buf[i]+‘0‘);return;
}
char map[1001][1001];//u行v列
int a[1001][1001],ans=0,m,n;
void res(int u,int v,int i,int j)
{
    int t=a[u][v];
    if(u==i&&v==j) ans=t;
    t++;//挨个搜
    if(u+2<=n&&v+1<=n&&map[u+2][v+1]!=‘#‘&&a[u+2][v+1]>t)
    {
        a[u+2][v+1]=t;
        res(u+2,v+1,i,j);
    }
    if(u+2<=n&&v-1>0&&map[u+2][v-1]!=‘#‘&&a[u+2][v-1]>t)
    {
        a[u+2][v-1]=t;
        res(u+2,v-1,i,j);
    }
    if(u-2>0&&v+1<=n&&map[u-2][v+1]!=‘#‘&&a[u-2][v+1]>t)
    {
        a[u-2][v+1]=t;
        res(u-2,v+1,i,j);
    }
    if(u-2>0&&v-1>0&&map[u-2][v-1]!=‘#‘&&a[u-2][v-1]>t)
    {
        a[u-2][v-1]=t;
        res(u-2,v-1,i,j);
    }
    if(v+2<=n&&u+1<=n&&map[u+1][v+2]!=‘#‘&&a[u+1][v+2]>t)

    {
        a[u+1][v+2]=t;
        res(u+1,v+2,i,j);
    }
    if(v+2<=n&&u-1>0&&map[u-1][v+2]!=‘#‘&&a[u-1][v+2]>t)
    {
        a[u-1][v+2]=t;
        res(u-1,v+2,i,j);
    }
    if(v-2>0&&u+1<=n&&map[u+1][v-2]!=‘#‘&&a[u+1][v-2]>t)
    {
        a[u+1][v-2]=t;
        res(u+1,v-2,i,j);
    }
    if(v-2>0&&u-1>0&&map[u-1][v-2]!=‘#‘&&a[u-1][v-2]>t)
    {
        a[u-1][v-2]=t;
        res(u-1,v-2,i,j);
    }
}
int main()
{
    int startx=1,starty=1,endx,endy,c,b;
    n=read(),m=read();
    memset(a,1,sizeof(a));
    memset(map,‘.‘,sizeof(map));
    endx=n;endy=n;
    map[1][1]=‘@‘;
    map[n][n]=‘*‘;
    for(int i=0;i<m;i++)
    {
        c=read(),b=read();
        map[c][b]=‘#‘;
    }
    a[startx][starty]=0;
    m=n;
    res(startx,starty,endx,endy);
    write(ans);
}

我的正解:

#include<iostream>
#include<queue>
using namespace std;
inline int read()
{
	int x=0,f=1;char c=getchar();
	for(;!isdigit(c);c=getchar()) if(c==‘-‘)f=-1;
	for(;isdigit(c);c=getchar()) x=x*10+c-‘0‘;
	return x*f;
}
int n,m,e[1001][1001],cur[1001][1001];
int b[8][2]={{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1},{-2,1},{-1,2}};
bool vis[1001][1001];
int bfs()
{
    queue<int>Q;
    Q.push(10001);
    vis[1][1]=1;
    while(Q.size())
    {
        int x=Q.front()/10000;
        int y=Q.front()%10000;
        Q.pop();
        for(int i=0;i<8;i++)
        {
            int xt=x+b[i][0],yt=y+b[i][1];
            if(xt>n || xt<1 || yt>n || yt<1) continue;
            if(e[xt][yt]!=-1 && !vis[xt][yt]){
                cur[xt][yt]=cur[x][y]+1;
                if(xt==n && yt==n) return cur[xt][yt];
                vis[xt][yt]=1;
                Q.push(xt*10000+yt);
            }
        }
    }
    return -1;
}
int main()
{
    int a,b;
    n=read(),m=read();
    for(int i=0;i<m;i++)
    {
        a=read(),b=read();
        e[a][b]=-1;
    }
    printf("%d",bfs());
}

地铁网络:

辛辛苦苦打了一个暴力,结果没过一个点 QAQ

#include<iostream>
#include<cstring>
#include<cmath>
inline int read(){
    int x=0,sig=1;char ch=getchar();
    while(!isdigit(ch)){if(ch==‘-‘)sig=-1;ch=getchar();}
    while(isdigit(ch))x=10*x+ch-‘0‘,ch=getchar();
    return x*=sig;
}
inline void write(int x){
    if(x==0){putchar(‘0‘);return;}if(x<0)putchar(‘-‘),x=-x;
    int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    for(int i=len-1;i>=0;i--)putchar(buf[i]+‘0‘);return;
}
using namespace std;
char str[250000][16],str2[200000][16],strstra[16],strans[250000][16];
int e[2500][2500],n,m,q,xy[250000][2],ans;// 3750000
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>str[i];
        xy[i][0]=read();
        xy[i][1]=read();
    }
    q=read();
    memset(e,999999,sizeof(e));
    for(int i=0;i<q;i++)
    {
        m=read();;
        for(int j=0;j<m;j++)
        {
            cin>>str2[j];
            for(int k=j-1;k>=0;k--)
            {
                int f,o;
                for(int p=0;p<n;p++)
                {
                    if(strcmp(str2[k],str[p])==0) f=p;
                    else if(strcmp(str2[j],str[p])==0) o=p;
                }
                e[f][o]=1;
                e[o][f]=1;
            }
        }
    }
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
        {
            if(i==j) e[i][j]=0;
            else if(e[i][j]==1) e[i][j]=abs(xy[i][0]-xy[j][0])+abs(xy[i][1]-xy[j][1]);
        }
    cin>>m>>strstra;
    int r=(m-3)*2000;
    int f;
    for(int p=0;p<n;p++)
         if(strcmp(strstra,str[p])==0) {f=p;break;}
    for(int k=0;k<n;k++)
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                e[i][j]=min(e[i][j],e[i][k]+e[k][j]);
    int num;
    for(int i=0;i<n;i++)
        if(e[f][i]>r&&e[f][i]<=r+2000)
        {
            for(int p=0;p<n;p++)
                 if(strcmp(str[i],str[p])==0) num=p;
            strcpy(strans[ans++],str[num]);
        }
    for(int i=0;i<ans-1;i++)
        for(int j=i+1;j<ans;j++)
        {
            if(strcmp(strans[i],strans[j])>0)
            {
                strcpy(strstra,strans[i]);
                strcpy(strans[i],strans[j]);
                strcpy(strans[j],strstra);
            }
        }
    for(int i=0;i<ans-1;i++)
    {
        int len=strlen(strans[i]);
        for(int j=0;j<len;j++)
            putchar(strans[i][j]);
        printf(" ");
    }
    int len=strlen(strans[ans-1]);
        for(int j=0;j<len;j++)
            putchar(strans[ans-1][j]);
}

思考题:传送门

这里给出我的这题的不包含变态输入的AC代码,大家可以尝试更改

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <set>
#include <queue>
#include <algorithm>
#define MAXN 205
#define RST(N)memset(N, 0, sizeof(N))
using namespace std;  

typedef struct _Node
{
    int x, y;
    int step;
}Node;  

Node p[MAXN], start;
char Map[MAXN][MAXN];
int v[MAXN][MAXN];
int n, m, res, cas;
int Sx, Sy, Ex, Ey, k;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
priority_queue <Node> pq;
int kdd;
bool operator < (Node a, Node b)
{
    return a.step > b.step;
}  

bool check(int x, int y)
{
    return x>=0 && y>=0 && x<n && y<m && Map[x][y]!=‘#‘ && !v[x][y];
}  

int BFS()
{
    Node cur;
    int px, py, xx, yy, cstep;
    while(!pq.empty()) {
        cur = pq.top(), pq.pop();
        px = cur.x, py = cur.y, cstep = cur.step;
        for(int i=0; i<4; i++) {
            xx = px + dx[i], yy = py + dy[i];
            if(check(xx, yy)) {
                if(xx == Ex && yy == Ey) return cstep+1;
                if(Map[xx][yy] == ‘T‘) {
                    for(int j=0; j<k; j++)
                    {
                        int fx = p[j].x, fy = p[j].y;
                        if(!v[fx][fy]) {
                            cur.x = fx, cur.y = fy;
                            cur.step = cstep + 2;
                            pq.push(cur);
                        }
                    }
                }else if(Map[xx][yy] == ‘.‘) {
                    cur.x = xx, cur.y = yy;
                    cur.step = cstep + 1;
                    pq.push(cur);
                }
                v[xx][yy] = 1;
            }
        }
    }
    return -1;
}
int main()
{
       cin>>n>>m;
        k = 0;
        for(int i=0; i<n; i++)
        {
            scanf("%s", Map[i]);
            for(int j=0; j<m; j++)
            {
                if(Map[i][j] == ‘T‘)
                {
                    p[k].x = i, p[k].y = j;
                    p[k++].step =0;
                }
            }
        }
        cin>>Sx>>Sy>>Ex>>Ey;
        Sx--,Sy--,Ex--,Ey--;
        RST(v);
        v[Sx][Sy] = 1;
        while(!pq.empty()) pq.pop();
        start.x = Sx, start.y = Sy, start.step = 0;
        pq.push(start);
        res = BFS();
        printf("%d\n", res);
}
时间: 2024-08-06 11:51:43

图论大赛的简单分析的相关文章

FFmpeg源代码简单分析:avformat_alloc_output_context2()

本文简单分析FFmpeg中常用的一个函数:avformat_alloc_output_context2().在基于FFmpeg的视音频编码器程序中,该函数通常是第一个调用的函数(除了组件注册函数av_register_all()).avformat_alloc_output_context2()函数可以初始化一个用于输出的AVFormatContext结构体.它的声明位于libavformat\avformat.h,如下所示. /** * Allocate an AVFormatContext

实时计算,流数据处理系统简介与简单分析

转自:http://www.csdn.net/article/2014-06-12/2820196-Storm 摘要:实时计算一般都是针对海量数据进行的,一般要求为秒级.实时计算主要分为两块:数据的实时入库.数据的实时计算.今天这篇文章详细介绍了实时计算,流数据处理系统简介与简单分析. 编者按:互联网领域的实时计算一般都是针对海量数据进行的,除了像非实时计算的需求(如计算结果准确)以外,实时计算最重要的一个需求是能够实时响应计算结果,一般要求为秒级.实时计算的今天,业界都没有一个准确的定义,什么

java基础----&gt;hashSet的简单分析(一)

对于HashSet而言,它是基于HashMap实现的,底层采用HashMap来保存元素的.今天我们就简单的分析一下它的实现. HashSet的简单分析 一.hashSet的成员变量组成 public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable private transient HashMap<E,Object> map;

FFmpeg的HEVC解码器源代码简单分析:解析器(Parser)部分

上篇文章概述了FFmpeg中HEVC(H.265)解码器的结构:从这篇文章开始,具体研究HEVC解码器的源代码.本文分析HEVC解码器中解析器(Parser)部分的源代码.这部分的代码用于分割HEVC的NALU,并且解析SPS.PPS.SEI等信息.解析HEVC码流(对应AVCodecParser结构体中的函数)和解码HEVC码流(对应AVCodec结构体中的函数)的时候都会调用该部分的代码完成相应的功能. 函数调用关系图 FFmpeg HEVC解析器(Parser)部分在整个HEVC解码器中的

x264源代码简单分析:熵编码(Entropy Encoding)部分

本文记录x264的 x264_slice_write()函数中调用的x264_macroblock_write_cavlc()的源代码.x264_macroblock_write_cavlc()对应着x264中的熵编码模块.熵编码模块主要完成了编码数据输出的功能. 函数调用关系图 熵编码(Entropy Encoding)部分的源代码在整个x264中的位置如下图所示. 单击查看更清晰的图片 熵编码(Entropy Encoding)部分的函数调用关系如下图所示.   单击查看更清晰的图片 从图中

u-boot分析(十一)----MMU简单分析|u-boot分析大结局|学习规划

u-boot分析(十一) 通过前面十篇博文,我们已经完成了对BL1阶段的分析,通过这些分析相信我们对u-boot已经有了一个比较深入的认识,在BL2阶段大部分是对外设的初始化,并且有的我们已经分析过,在这篇博文我打算对BL1阶段没有分析到的重要外设进行简单分析,并结束对u-boot的分析,同时对后面自己的博文进行简单的规划,希望有兴趣的朋友跟我一块学习和研究嵌入式. 今天我们会分析到以下内容: 1.      MMU分析(内容出自我以前的博客) 2.      裸机开发总结 3.      后期

Collections中sort()方法源代码的简单分析

Collections的sort方法代码: public static <T> void sort(List<T> list, Comparator<? super T> c) { Object[] a = list.toArray(); Arrays.sort(a, (Comparator)c); ListIterator i = list.listIterator(); for (int j=0; j<a.length; j++) { i.next(); i.

netback的tasklet调度问题及网卡丢包的简单分析

最近在万兆网卡上测试,出现了之前千兆网卡没有出现的一个现象,tasklet版本的netback下,vm进行发包测试,发现vif的interrupt默认绑定在cpu0上,但是vm发包运行时发现host上面cpu1, cpu2的ksoftirqd很高. 从之前的理解上来说,包从netfront出来通过eventchannel notify触发vif的irq处理函数,然后tasklet_schedule调用tx_action,通过一系列处理流程把包发给网卡.所以vif的interrupt绑在哪个cpu

搜索引擎原理之链接原理的简单分析

在google诞生以前,传统搜索引擎主要依靠页面内容中的关键词匹配搜索词进行排名.这种排名方式的短处现在看来显而易见,那就是很容易被刻意操纵.黑帽SEO在页面上推挤关键词,或加入与主题无关的热门关键词,都能提高排名,使搜索引擎排名结果质量大为下降.现在的搜索引擎都使用链接分析技术减少垃圾,提高用户体验.下面泡馆史明星就来简单的介绍链接在搜索引擎排名中的应用原理. 在排名中计入链接因素,不仅有助于减少垃圾,提高结果相关性,也使传统关键词匹配无法排名的文件能够被处理.比如图片.视频无法进行关键词匹配