补题

扫码查看

10.8 c

https://vjudge.net/contest/332874#problem/C

#include<iostream >
using namespace std;
const int maxn=2e5+10;
char a[2][maxn];
int len,n;
bool flag;
void dfs(int x,int y,int d)//x,y为坐标点,d=1向上,d=2向下,d=3向右(由于可以旋转,3,4,5,6可以当成一个) 
{
    if(y>=len)
      return;
    if(x==1&&y==len-1&&d==3)//到达"终点" 
    {
         flag=1;
         return;
    }
    if(x==0)//在第一行,向右或向下 
    {
        if(d==3)
        {
            if(a[x][y+1]=='1'||a[x][y+1]=='2')
              dfs(x,y+1,3);
            else
              dfs(x,y+1,2);
        }
        else if(d==2)
        {
            if(a[x+1][y]!='1'&&a[x+1][y]!='2')
               dfs(x+1,y,3);
        }
    }
    else if(x==1)//在第二行,向右或向上
    {
        if(d==3)
        {
            if(a[x][y+1]!='1'&&a[x][y+1]!='2')
              dfs(x,y+1,1);
            else
              dfs(x,y+1,3);
        }
        else if(d==1)
        {
            if(a[x-1][y]!='1'&&a[x-1][y]!='2')
               dfs(x-1,y,3);
        }
    }

}
int main()
{
    cin>>n;
    while(n--)
    {
        flag=0;
        cin>>len;
        cin>>a[0];
        cin>>a[1];
        if(a[0][0]=='1'||a[0][0]=='2')
           dfs(0,0,3);
        else
           dfs(0,0,2);
        if(flag)
           cout<<"YES"<<endl;
        else
           cout<<"NO"<<endl;
    }
    return 0;
}

 10.9

https://vjudge.net/contest/333223#problem/B

这道题考查的是最短路,floyd算法的应用

由于对于任意一条至少包含两条边的路径i--j,一定存在一个中间点,使得i--k+k--j=i--j,当然,对于不同的点k,i--k和k--j的长度值可能不同,

所以需要取一个最小值才是最短路径

e[i][j]=min(e[i][j],max(e[i][k],e[k][j]));
max是取从i--j中,以k为节点,能承受的最大噪音分贝值,然后从这些最大中再选出最小的那个路径,就是最短路径
#include<iostream>
using namespace std;
int e[1010][1010];
int inf=0x3f3f3f3f;
int c,s,q;
int main()
{
    int c1,c2,d,x=1,a,b;
    while(cin>>c>>s>>q)
    {
        if(c==0&&s==0&&q==0)break;
        if(x!=1)cout<<endl;
        //初始化 
        for(int i=0;i<=c;i++)
          for(int j=0;j<=c;j++)
            if(i==j)e[i][j]=0;
            else  e[i][j]=inf;

        for(int i=1;i<=s;i++)
        {
            cin>>c1>>c2>>d;
            e[c1][c2]=d;
            e[c2][c1]=d;
        }
        cout<<"Case #"<<x<<endl;

        for(int k=0;k<=c;k++)
          for(int i=0;i<=c;i++)
            for(int j=0;j<=c;j++)
                e[i][j]=min(e[i][j],max(e[i][k],e[k][j]));

        for(int i=0;i<q;i++)
        {
            cin>>a>>b;
            if(e[a][b]==inf)
               cout<<"no path"<<endl;
            else
               cout<<e[a][b]<<endl;
        }
        x++;
    }
    return 0;
}

 10.11

A - Slim Span

 UVA - 1395 

给你一个图,点以及权值,找出查找的两点间最小差值

kruskal算法,
#include<iostream>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
int n,m,flag,f[5500];
struct node
{
    int u,v,w;
}s[5500];
bool cmp(node x,node y)
{
    return x.w<y.w;
}
int getf(int v)//并查集找祖先 
{
    if(f[v]==v)
      return v;
    else
    {
        f[v]=getf(f[v]);
        return f[v];
    }
}
void kruskal()
{
    for(int i=0;i<m;i++)
    {
        int cnt=0;
        for(int j=0;j<=n;j++)
          f[j]=j;
        for(int j=i;j<m;j++)//并查集合并 
        {
            int t1=getf(s[j].u);
            int t2=getf(s[j].v);
            if(t1!=t2)//两个点是否在一个集合里 
            {
                cnt++;
                f[t2]=t1;
                 if(cnt==n-1)
                 {
                     flag=min(flag,s[j].w-s[i].w);
                     break;
                 }
            }
        }
    }
}
int main()
{
    while(cin>>n>>m&&(n||m))
    {
        for(int i=0;i<m;i++)
           cin>>s[i].u>>s[i].v>>s[i].w;
        sort(s,s+m,cmp);
        flag=inf;
        kruskal();
        if(flag==inf)
           cout<<"-1"<<endl;
        else
          cout<<flag<<endl;

    }
    return 0;
}

B - Resort

 CodeForces - 350B 

Valera's finally decided to go on holiday! He packed up and headed for a ski resort.

Valera's fancied a ski trip but he soon realized that he could get lost in this new place. Somebody gave him a useful hint: the resort has n objects (we will consider the objects indexed in some way by integers from 1 to n), each object is either a hotel or a mountain.

Valera has also found out that the ski resort had multiple ski tracks. Specifically, for each object v, the resort has at most one object u, such that there is a ski track built from object u to object v. We also know that no hotel has got a ski track leading from the hotel to some object.

Valera is afraid of getting lost on the resort. So he wants you to come up with a path he would walk along. The path must consist of objects v, v, ..., v (k ≥ 1) and meet the following conditions:

  1. Objects with numbers v, v, ..., v are mountains and the object with number v is the hotel.
  2. For any integer i (1 ≤ i < k), there is exactly one ski track leading from object v. This track goes to object v.
  3. The path contains as many objects as possible (k is maximal).

Help Valera. Find such path that meets all the criteria of our hero!

Input

The first line contains integer n (1 ≤ n ≤ 10) — the number of objects.

The second line contains n space-separated integers type, type, ..., type — the types of the objects. If type equals zero, then the i-th object is the mountain. If type equals one, then the i-th object is the hotel. It is guaranteed that at least one object is a hotel.

The third line of the input contains n space-separated integers a, a, ..., a (0 ≤ a ≤ n) — the description of the ski tracks. If number a equals zero, then there is no such object v, that has a ski track built from v to i. If number a doesn't equal zero, that means that there is a track built from object a to object i.

Output

In the first line print k — the maximum possible path length for Valera. In the second line print k integers v, v, ..., v — the path. If there are multiple solutions, you can print any of them.

Examples

Input
5
0 0 0 0 1
0 1 2 3 4
Output
5
1 2 3 4 5
Input
5
0 0 1 0 1
0 1 2 2 4
Output
2
4 5
Input
4
1 0 0 0
2 3 4 2
Output
1
1

题意:n为所给数长度
第一排数0是表示山,1表示酒店
第二排数是表示可走的滑道
如样例2
5
序号  1 2 3 4 5
0 0 1 0 1
二排 0 1 2 2 4
0--1
1--2
2--3
2--4
4--5(只有3和5是酒店,2既可以到3又可以到4,不满足题目条件,所以选择包含尽可能多的节点)
答案为4--5
两个代码,思路异曲同工
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
int n;
int a[maxn],b[maxn],c[maxn],p[maxn];
bool vis[maxn];
int main()
{
    cin>>n;
    memset(c,0,sizeof(c));
    memset(vis,false,sizeof(vis));
    for(int i=0;i<maxn;i++)
       p[i]=i;

    for(int i=1;i<=n;i++)
       cin>>a[i];
    for(int i=1;i<=n;i++)
    {
       cin>>b[i];
       c[b[i]]++;//记录出度
    }
    for(int i=1;i<=n;i++)
    {
         if(c[b[i]]<=1)
         {
             p[b[i]]=i;//记录满足的节点 
        }
    }
    int dx=0,dc=1;
    for(int i=1;i<=n;i++)
    {
        if(vis[i]) continue;
        if(c[i]<=1)
        {
            int t=i,z=1;//z控制可执行的点,从一个跳到可执行的点
            while(p[t]!=t&& !vis[i])
            {
                if(c[t]>1)break;
                z++,t=p[t];
                vis[t]=true;
            }
            if(a[t]==1&&z>dx)
               dx=max(dx,z),dc=i;
        }
        vis[i]=true;
    }
    cout<<dx<<endl;
    while(p[dc]!=dc)
    {
        cout<<dc<<" ";
        dc=p[dc];
    }
    cout<<dc<<endl;
      return 0;
}

将可执行的点存数组,倒序查找

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=100000;
int n,a[maxn],b[maxn],c[maxn];
int main()
{
    scanf("%d",&n);
    for (int i=0;i<n;i++)
        scanf("%d",&a[i]);
    for (int i=0;i<n;i++){
        scanf("%d",&b[i]);
        b[i]--;
    }
    for (int i=0;i<n;i++)
        c[i]=0;
    for (int i=0;i<n;i++)
        if (b[i]!=-1)
            c[b[i]]++;//可走的路 
    int ret=0,reti=-1;
    for (int i=0;i<n;i++)
        if (a[i]==1){
            int x=1;
            int j=i;
            while (b[j]!=-1 && c[b[j]]==1){//查到酒店跳转查看前一个 
                j=b[j];
                x++;//记录次数 
            }
            if (x>ret){//最长 
                ret=x;
                reti=i;
            }
        }
    printf("%d\n",ret);
    vector<int> output;
    for (int i=0;i<ret;i++){
        output.push_back(reti);//倒序放入 
        reti=b[reti];
    }
    for (int i=0;i<ret;i++){
        if (i)
            printf(" ");
        printf("%d",output[ret-1-i]+1);
    }
    puts("");
    return 0;
}

02-11 11:39
查看更多