码迷,mamicode.com
首页 > 其他好文 > 详细

图论大赛的简单分析

时间:2016-07-30 23:54:16      阅读:310      评论:0      收藏:0      [点我收藏+]

标签:

总体分析:

    第一道题:一个字!水!!,只不过看数据的话那个第五个测评点会非常大,需要一个并查集剪枝维护才能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);  
}

 

图论大赛的简单分析

标签:

原文地址:http://www.cnblogs.com/wxjor/p/5721939.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!