假期第一次集训题解

这次集训主要是对于基本逻辑还有基本算法的训练,基本算法就是对于并查集,深度优先搜索,广度优先搜索一些理解与应用,选的题都是比较适合入门的题,比较简单。

 

 

A:

一道几何题,我没有做,放下题解代码。

#include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<cmath>

using namespace std;

int T,a,b;

const double pi=3.1415926535897932;

enum type

{

    EMPTY=0,

    FULL=1,

    FLE=2,

    FGE=3,

    ELF=4,

    EGF=5,

    FLEFL=6,

    FGEFL=7,

    FLEFG=8,

    ELFEL=9,

    EGFEL=10,

    ELFEG=11,

};

void gettype(int a,int b,int& tar,int& t1,int& t2)

{

    if(a>=180)

    {

        if(b>a)tar=FULL;

        else if(b<=90)tar=FGE,t1=b;

        else if(b<180)tar=FLE,t1=b;

        else tar=EMPTY;

    }else if(a<90)

    {

        if(b>=180||b==0)tar=EGF,t1=a;

        else if(b>90)tar=FLEFL,t1=b,t2=a;

        else if(b>a)tar=FGEFL,t1=b,t2=a;

        else if(b>0)tar=EGFEL,t1=a,t2=b;

    }else if(a>=90)

    {

        if(b>=180||b==0)tar=ELF,t1=a;

        else if(b<=90)tar=ELFEL,t1=a,t2=b;

        else if(b<a)tar=ELFEG,t1=a,t2=b;

        else if(b<180)tar=FLEFG,t1=b,t2=a;

    }

}

double torad(double d) 

    return pi/180.0*d;

double gettotal(int t,double t1,double t2)

{

    if(t==EMPTY)return 0.0;

    if(t==FULL)return 1.0;

    if(t==FLE)return sin(t1);

    if(t==FGE)return 1.0;

    if(t==ELF)return 1.0;

    if(t==EGF)return sin(t1);

    if(t==FLEFL)return max(sin(t1),sin(t2));

    if(t==FGEFL)return 1.0;

    if(t==FLEFG)return 1.0;

    if(t==ELFEL)return 1.0;

    if(t==EGFEL)return sin(t1);

    if(t==ELFEG)return sin(t2);

}

double getred(int t,double t1,double t2)

{

    if(t==EMPTY)return 0.0;

    if(t==FULL)return 0.0;

    if(t==FLE)return sin(t1);

    if(t==FGE)return sin(t1);

    if(t==ELF)return 0.0;

    if(t==EGF)return 0.0;

    if(t==FLEFL)return max(0.0,sin(t1)-sin(t2));

    if(t==FGEFL)return sin(t1)-sin(t2);

    if(t==FLEFG)return 0.0;

    if(t==ELFEL)return sin(t2);

    if(t==EGFEL)return sin(t2);

    if(t==ELFEG)return sin(t2);

}

int tl,tr;

int tl1,tl2,tr1,tr2;

int main()

{

    cin>>T;

    while(T--)

    {

        cin>>a>>b;

        gettype(a,b,tr,tr1,tr2);

        a=(-a+360)%360;

        b=(-b+360)%360;

        swap(a,b);

        gettype(a,b,tl,tl1,tl2);

        double totl=gettotal(tl,torad(tl1),torad(tl2));

        double totr=gettotal(tr,torad(tr1),torad(tr2));

        double redl=getred(tl,torad(tl1),torad(tl2));

        double redr=getred(tr,torad(tr1),torad(tr2));

        printf("%.1lf%%\n",(redl+redr)*100.0/(totl+totr));

    }

    return 0;

}

 

B题:

一道关于异或的线性基问题。

/*

    求线性基即可

*/

#include<iostream>

#include<cstdio>

#include<cstring>

#define maxn 55

using namespace std;

int n;

long long a[maxn],b[maxn];

int main(){

    scanf("%d",&n);

    for(int i=1;i<=n;i++)cin>>a[i];

    for(int i=1;i<=n;i++){

        for(int j=50;j>=0;j--){

            if((a[i]>>j)&1){

                if(b[j])a[i]^=b[j];

                else {

                    b[j]=a[i];

                    for(int k=j-1;k>=0;k--)if((b[j]>>k)&1)b[j]^=b[k];

                    for(int k=j+1;k<=50;k++)if((b[k]>>j)&1)b[k]^=b[j];

                    break;

                }

            }

        }

    }

    long long ans=0;

    for(int i=0;i<=50;i++)ans^=b[i];

    cout<<ans;

    return 0;

}

C题:

一道简单的搜索,我采用了深搜和广搜俩种写法。不懂得可以看看。

# include <iostream>

# include <queue>

# include <cstring>

 

using namespace std;

 

const int maxn = 25;

bool vis[maxn][maxn];

char str[maxn][maxn];

int n, m, sx, sy, ex,ey;

int dis[][2] = {0, 1, 0, -1, 1, 0, -1, 0};

 

 

struct node

{

    int x, y;

};

# if 0

bool bfs()

{

    queue<struct node> q;

    struct node temp, front;

    front.x = sx;

    front.y = sy;

    q.push(front);

    while(!q.empty())

    {

        temp = q.front();

        q.pop();

        if(temp.x == ex && temp.y == ey)

        {

            return true;

        }

        for(int i = 0; i < 4; i++)

        {

            int tx = temp.x + dis[i][0];

            int ty = temp.y + dis[i][1];

            if(str[tx][ty] != '.' || tx < 0 || tx >= n || ty < 0 ||ty >= m)

            {

                continue;

            }

            if(!vis[tx][ty])

            {

                vis[tx][ty] = 1;

                front.x = tx;

                front.y = ty;

                q.push(front);

            }

        }

    }

    return false;

}

 

# endif

bool flag;

void dfs(int x, int y)

{

    if(flag)

    {

        return ;

    }

    if(x == ex && y == ey)

    {

        flag = true;

        return ;

    }

    for(int i = 0; i < 4; i++)

    {

        int tx = x + dis[i][0];

        int ty = y + dis[i][1];

        if(str[tx][ty] != '.' || tx < 0 || tx >= n || ty < 0 ||ty >= m)

        {

            continue;

        }

        if(!vis[tx][ty])

        {

            vis[tx][ty] = true;

            dfs(tx, ty);

            vis[tx][ty] = false;

        }

    }

}

 

int main(int argc, char *argv[])

{

    while(cin >> m >> n, (m||n))

    {

        flag = false;

        memset(vis, false, sizeof(vis));

        for(int i = 0; i < n; i++)

        {

            cin >> str[i];

        }

        for(int i = 0; i < n; i++)

        {

            for(int j = 0; j < m; j++)

            {

                if(str[i][j] == 'S')

                {

                    sx = i;

                    sy = j;

                }

                if(str[i][j] == 'P')

                {

                    str[i][j] = '.';

                    ex = i;

                    ey = j;

                }

            }

        }

        # if 0

        if(bfs())

        {

            cout << "YES" << endl;

        }

        else

        {

            cout << "NO" << endl;

        }

        # endif

        dfs(sx, sy);

        if(flag)

        {

            cout << "YES" << endl;

        }

        else

        {

            cout << "NO" << endl;

        }

 

    }

    return 0;

}

D题:

阶乘问题。

# include <iostream>

# include <queue>

# include <cstring>

 

using namespace std;

 

const int maxn = 25;

int a[13];

void fun()

{

    int k = 1;

    for(int i = 1; i <= 12; i++)

    {

        k *= i;

        a[i] = k;

    }

}

 

int main(int argc, char *argv[])

{

    int n;

    fun();

    while(cin >> n)

    {

        while(n--)

        {

            int m;

            cin >> m;

            cout << a[m] <<endl;

        }

    }

    return 0;

}

E:

一道简单的dp问题,又是一道记忆化搜索的简单应用

# include <iostream>

# include <queue>

# include <cstring>

 

using namespace std;

 

const int maxn = 26;

int dp[maxn][maxn][maxn];

const int maxx = 0x3f3f3f3f;

 

void fun()

{

    for(int i = 0; i < 26; i++)

    {

        for(int j = 0; j < 26; j++)

        {

            for(int k = 0; k < 26; k++)

            {

                dp[i][j][k] = maxx;

            }

        }

    }

}

 

int w(int a, int b, int c)

{

    if(dp[a][b][c] != maxx)

    {

        return dp[a][b][c];

    }

    if(a <= 0 || b <= 0 || c <= 0)

    {

        return 1;

    }

    if(a > 20 || b > 20 || c > 20)

    {

        return w(20, 20, 20);

    }

    if(a < b && b < c)

    {

        dp[a][b][c] = w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, c);

    }

    else

    {

        dp[a][b][c] = w(a-1, b, c) + w(a-1, b-1, c) + w(a-1, b, c-1) - w(a-1, b-1, c-1);

    }

    return dp[a][b][c];

}

 

int main(int argc, char *argv[])

{

    int n;

 

    while(cin >> n)

    {

        while(n--)

        {

            fun();

            int a, b, c;

            cin >> a >> b >> c;

            cout << w(a, b, c) << endl;

        }

    }

    return 0;

}

F题:

# include <iostream>

# include <queue>

# include <cstring>

# include <iomanip>

 

using namespace std;

 

const int maxn = 26;

int dp[maxn][maxn][maxn];

const int maxx = 0x3f3f3f3f;

 

int main(int argc, char *argv[])

{

    double x;

 

    while(cin >> x)

    {

        cout << fixed << setprecision(1);

        if(x > 0)

        {

 

            cout << x * x + 1 << endl;

        }

        else if(x < 0)

        {

            cout << -x << endl;

        }

        else

        {

            cout << 100.00 << endl;

        }

    }

    return 0;

}

G题:

打印杨辉三角

# include <iostream>

# include <queue>

# include <cstring>

# include <iomanip>

 

using namespace std;

 

const int maxn = 35;

int dp[maxn][maxn];

const int maxx = 0x3f3f3f3f;

 

 

int main(int argc, char *argv[])

{

    int n;

    while(cin >> n, n)

    {

        memset(dp, false, sizeof(dp));

        dp[1][1] = 1;

        for(int i = 2; i <= n; i++)

        {

            for(int j = 1; j <= i; j++)

                dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1];

        }

        for(int i = 1; i <= n; i++)

        {

            int p = 0;

            for(int j = 1; j <= i; j++)

            {

                if(p++)

                {

                    cout << " ";

                }

                cout << dp[i][j];

            }

            cout << endl;

        }

        cout << endl;

    }

    return 0;

}

 

 

H题:

可以找规律也可以用数学的方法来做,因为根据一个大数模除一个数,可以拆成好多个小的数模除一个数然后相加在模除

# include <iostream>

# include <queue>

# include <cstring>

# include <iomanip>

 

using namespace std;

 

const int maxn = 35;

int dp[maxn][maxn];

const int maxx = 0x3f3f3f3f;

 

 

int main(int argc, char *argv[])

{

    int n;

    while(cin >> n)

    {

        if(n < 2)

        {

            cout << "no" << endl;

        }

        else

        {

            int a = 7, b = 11, c;

            for(int i = 2; i <= n; i++)

            {

                c = (a + b) % 3;

                a = b;

                b = c;

            }

            if(c)

            {

                cout << "no" << endl;

            }

            else

            {

                cout << "yes" << endl;

            }

        }

    }

    return 0;

}

 

I题:

# include <iostream>

# include <queue>

# include <cstring>

# include <iomanip>

 

using namespace std;

 

const int maxn = 45;

int dp[maxn];

const int maxx = 0x3f3f3f3f;

 

void fun()

{

    dp[1] = 1, dp[2] = 1;

    for(int i = 3; i <= 41; i++)

    {

        dp[i] = dp[i - 1] + dp[i - 2];

    }

}

 

int main(int argc, char *argv[])

{

    int n;

    fun();

    while(cin >> n)

    {

        int p = 0;

        for(int i = 1; i <= n; i++)

        {

            if(p++)

            {

                cout << " ";

            }

            cout << dp[i];

        }

        cout << endl;

    }

    return 0;

}

J题:

简单递归。

# include <iostream>

# include <queue>

# include <cstring>

# include <iomanip>

 

using namespace std;

 

const int maxn = 45;

int dp[maxn];

const int maxx = 0x3f3f3f3f;

 

int fun(int x)

{

    if(x == 1)

    {

        return 10;

    }

 

    return fun(x - 1) + 2;

}

 

int main(int argc, char *argv[])

{

    int n;

 

    while(cin >> n)

    {

       cout << fun(n) << endl;

    }

    return 0;

}

 

K题:

一道水的并查集只要判断输入的数根是不是相同就行。相同说明就有俩条以上的路不同就合并然后继续输入。

# include <iostream>

# include <cstring>

# include <algorithm>

 

using namespace std;

 

const int maxn = 100005;

 

int pre[maxn];

 

int find(int x)

{

    if(x != pre[x])

    {

        pre[x] = find(pre[x]);

    }

    return pre[x];

}

 

void join(int x, int y)

{

    int tx = find(x);

    int ty = find(y);

    if(tx != ty)

    {

        pre[ty] = tx;

    }

}

 

void fun()

{

    for(int i = 0; i < maxn; i++)

    {

        pre[i] = i;

    }

}

 

 

int main(int argc, char *asrgv[])

{

    int x, y;

    fun();

    bool flag = false;

    while(cin >> x >> y, x != - 1 && y!= -1)

    {

        if(x == 0 && y == 0)

        {

            if(!flag)

            {

                cout << "Yes" << endl;

            }

            else

            {

                cout << "No" << endl;

            }

            flag = false;

            fun();

        }

        else

        {

            if(!flag)

            {

                if(find(x) != find(y))

                {

                   join(x, y);

                }

                else

                {

                    flag = true;

                }

            }

        }

 

    }

 

    return 0;

}

 

L题:

找一下一有几个不同的根就行然后-1就是需要修的路

# include <iostream>

# include <cstring>

# include <algorithm>

 

using namespace std;

 

const int maxn = 100005;

 

int pre[maxn];

 

int find(int x)

{

    if(x != pre[x])

    {

        pre[x] = find(pre[x]);

    }

    return pre[x];

}

 

void join(int x, int y)

{

    int tx = find(x);

    int ty = find(y);

    if(tx != ty)

    {

        pre[ty] = tx;

    }

}

 

void fun()

{

    for(int i = 0; i < maxn; i++)

    {

        pre[i] = i;

    }

}

 

 

int main(int argc, char *asrgv[])

{

    int n, m;

    while(cin >> n >> m)

    {

       fun();

       for(int  i = 0; i < m; i++)

       {

           int x, y;

           cin >> x >> y;

           join(x, y);

       }

       int arr[maxn] = {0};

       for(int i = 1; i <= n; i++)

       {

           arr[find(pre[i])]++;

       }

       int sum = 0;

       for(int i = 0; i <= n; i++)

       {

           if(arr[i])

           {

               sum++;

           }

       }

        cout << sum - 1 << endl;

    }

 

    return 0;

}

 

M题:

换汤不换药还是问有几个根的问题。

# include <iostream>

# include <cstring>

# include <algorithm>

 

using namespace std;

 

const int maxn = 100005;

 

int pre[maxn];

 

int find(int x)

{

    if(x != pre[x])

    {

        pre[x] = find(pre[x]);

    }

    return pre[x];

}

 

void join(int x, int y)

{

    int tx = find(x);

    int ty = find(y);

    if(tx != ty)

    {

        pre[ty] = tx;

    }

}

 

void fun()

{

    for(int i = 0; i < maxn; i++)

    {

        pre[i] = i;

    }

}

 

 

int main(int argc, char *asrgv[])

{

    int n, m;

    int t;

    while(cin >> t)

    {

        while(t--)

        {

            cin >> n >> m;

            fun();

            for(int  i = 0; i < m; i++)

            {

                int x, y;

                cin >> x >> y;

                join(x, y);

            }

            int arr[maxn] = {0};

            for(int i = 1; i <= n; i++)

            {

                arr[find(pre[i])]++;

            }

            int sum = 0;

            for(int i = 0; i <= n; i++)

            {

                if(arr[i])

                {

                    sum++;

                }

            }

            cout << sum << endl;

        }

    }

 

    return 0;

}

 

 

N题:

换汤不换药还是问有几个不同的根

# include <iostream>

# include <cstring>

# include <algorithm>

 

using namespace std;

 

const int maxn = 100005;

 

int pre[maxn];

 

int find(int x)

{

    if(x != pre[x])

    {

        pre[x] = find(pre[x]);

    }

    return pre[x];

}

 

void join(int x, int y)

{

    int tx = find(x);

    int ty = find(y);

    if(tx != ty)

    {

        pre[ty] = tx;

    }

}

 

void fun()

{

    for(int i = 0; i < maxn; i++)

    {

        pre[i] = i;

    }

}

 

 

int main(int argc, char *asrgv[])

{

    int n, m;

    int t;

    while(cin >> n)

    {

        if(n == 0)

        {

            break;

        }

        cin >> m;

        fun();

        for(int  i = 0; i < m; i++)

        {

            int x, y;

            cin >> x >> y;

            join(x, y);

        }

        int arr[maxn] = {0};

        for(int i = 1; i <= n; i++)

        {

            arr[find(pre[i])]++;

        }

        int sum = 0;

        for(int i = 0; i <= n; i++)

        {

            if(arr[i])

            {

                sum++;

            }

        }

        cout << sum << endl;

 

    }

 

    return 0;

}

 

O题:

还是问有几个不同的根,然后注意下特判下有没有朋友关系

# include <iostream>

# include <cstring>

# include <algorithm>

 

using namespace std;

 

const int maxn = 100005;

 

int pre[maxn];

 

int find(int x)

{

    if(x != pre[x])

    {

        pre[x] = find(pre[x]);

    }

    return pre[x];

}

 

void join(int x, int y)

{

    int tx = find(x);

    int ty = find(y);

    if(tx != ty)

    {

        pre[ty] = tx;

    }

}

 

void fun()

{

    for(int i = 0; i < maxn; i++)

    {

        pre[i] = i;

    }

}

 

 

int main(int argc, char *asrgv[])

{

    int n, m;

    int t;

    while(cin >> t)

    {

        while(t--)

        {

            cin >> n >> m;

            fun();

            for(int  i = 0; i < m; i++)

            {

                int x, y;

                cin >> x >> y;

                join(x, y);

            }

            int arr[maxn] = {0};

            for(int i = 1; i <= n; i++)

            {

                arr[find(pre[i])]++;

            }

            bool flag = false;

            int sum1 = 0, sum2 = 0;

            for(int i = 1; i <= n; i++)

            {

 

                if(arr[i] > 1)

                {

                    flag = true;

                    sum1++;

                }

                if(arr[i])

                {

                    sum2++;

                }

            }

        //    cout << "sum1 = " << sum1 << " " << "sum2 = " << sum2 << endl;

          

            if(flag)

            {

               cout <<sum2 <<endl;

            }

            else

            {

                cout << n << endl;

            }

 

        }

    }

 

    return 0;

}

 

P题:

这是一个关于栈的问题,要求符合栈的顺序输出。可以拿栈来模拟。理解题意就是一道水题了

#include<cstdio>

#include<stack>

#include<iostream>

using namespace std;

int a[1000];

int main()

{

    int n,i,k;

    while(scanf("%d",&n)&&n)

    {

        stack <int> s;

        while(scanf("%d",&a[0])&&a[0])

        {

            for(i=1;i<n;i++)

                cin >> a[i];

            //找到我对应的然后全退出去

            for(i=1,k=0;i<=n;i++)

            {

                s.push(i);

                while(s.top()==a[k])

                {

                    if(!s.empty())

                        s.pop();

                    k++;

                    if(s.empty())

                        break;

                }

            }

            if(k==n)

                cout << "Yes" << endl;

            else

                cout << "No" << endl;

        }

        cout << endl;

     }

     return 0;

}

 

 

Q题:

最小生成树问题,可以用克鲁斯卡尔算法求解也可以用,prim算法,我用的克鲁斯卡尔算法。

# include <iostream>

# include <cstring>

# include <algorithm>

# include <iomanip>

# include <cstdio>

 

using namespace std;

 

const int maxn = 100005;

 

struct node

{

    int x, y;

    double z;

}f[maxn];

 

int pre[maxn];

 

int find(int x)

{

    if(x != pre[x])

    {

        pre[x] = find(pre[x]);

    }

    return pre[x];

}

 

void join(int x, int y)

{

    int tx = find(x);

    int ty = find(y);

    if(tx != ty)

    {

        pre[ty] = tx;

    }

}

 

void fun()

{

    for(int i = 0; i < maxn; i++)

    {

        pre[i] = i;

        f[i].x = f[i].y = f[i].z = 0;

    }

 

}

bool cmp(node a, node b)

{

    return a.z < b.z;

}

 

int main(int argc, char *asrgv[])

{

    double s;

    cin >> s;

    {

       fun();

       int n, m;

       cin >> n ;

       m = 0;

        while(cin >> f[m].x >> f[m].y >> f[m].z)

        {

         //   cout << f[m].x << "--" << f[m].y << "--" << f[m].z << endl;

            m++;

        }

 

 

       sort(f, f + m, cmp);

 

       int num = 0;

       double ss = 0;

       for(int i = 0; i < m; i++)

       {

           if(find(f[i].x) != find(f[i].y))

           {

           //    cout << f[i].x << "--" << f[i].y << "--" << f[i].z << endl;

               join(f[i].x, f[i].y);

               num++;

               ss += f[i].z;

           }

           if(num == n - 1)

           {

               break;

           }

       }

    

       if(ss <= s && num == n - 1)

       {

           cout << fixed << setprecision(2);

           cout << "Need "<< ss<<" miles of cable" <<endl;

       }

       else

       {

           cout << "Impossible" <<endl;

       }

  

    }

 

    return 0;

}

 

R题:

一道搜索题,需要计算杀掉守卫快还是绕路快。然后让优先级高的先出队,我这里采用了优先队列应该可以设一个变量做一下标记,遇见守卫后出队也可以。

# include <iostream>

# include <queue>

# include <cstring>

# include <algorithm>

 

using namespace std;

 

const int maxn = 205;

const int maxx = 0x3f3f3f3f;

bool vis[maxn][maxn];

char str[maxn][maxn];

int n, m, t,sx, sy, ex,ey;

int dis[][2] = {0, 1, 0, -1, 1, 0, -1, 0};

int num;

 

struct node

{

    int x, y, t;

 

}s[maxn];

 

struct cmp

{

   bool operator () (const node a, const node b)

    {

        return a.t > b.t;

    }

};

bool bfs()

{

    priority_queue<node, vector<node>, cmp> q;

    struct node temp, f;

    for(int i = 0; i < num; i++)

    {

        f.x = s[i].x;

        f.y = s[i].y;

        f.t = 0;

        q.push(f);

    }

    while(!q.empty())

    {

        temp = q.top();

        q.pop();

        if(temp.x == ex && temp.y == ey && temp.t < t)

        {

                t = temp.t;

        }

        for(int i = 0; i < 4; i++)

        {

            int tx = temp.x + dis[i][0];

            int ty = temp.y + dis[i][1];

            if(str[tx][ty] == '#' || tx < 0 || tx >= n || ty < 0 ||ty >= m || temp.t + 1 >= t)

            {

                continue;

            }

            if(!vis[tx][ty])

            {

                vis[tx][ty] = 1;

                if(str[tx][ty] == 'x')

                {

                    f.t = temp.t + 2;

                }

                else

                {

                    f.t = temp.t + 1;

                }

                f.x = tx;

                f.y = ty;

                q.push(f);

            }

        }

    }

    if(t != maxx)

    {

        return true;

    }

    return false;

}

int main(int argc, char *argv[])

{

 

    while(cin >> n >> m)

    {

        t = maxx;

        num = 0;

        memset(vis, false, sizeof(vis));

 

        for(int i = 0; i < n; i++)

        {

            cin >> str[i];

        }

        for(int i = 0; i < n; i++)

        {

            for(int j = 0; j < m; j++)

            {

 

                if(str[i][j] == 'a')

                {

                    ex = i;

                    ey = j;

                    str[i][j] = '.';

                }

                if(str[i][j] == 'r')

                {

                    sx = i;

                    sy = j;

                     s[num].x = i;

                     s[num++].y = j;

 

                }

            }

        }

        bfs();

        if(t == maxx)

        {

            cout << "Poor ANGEL has to stay in the prison all his life." <<endl;

        }

        else

            cout << t << endl;

    }

 

    return 0;

}

 

S题:

广搜的记录路径,深搜过不去。

# include <iostream>

# include <queue>

# include <cstring>

# include <algorithm>

# include <string>

 

using namespace std;

 

const int maxn = 105;

const int maxx = 0x3f3f3f3f;

bool vis[maxn][maxn];

char str[maxn][maxn];

int n, m, t,sx, sy, ex,ey;

int dis[][2] = {0, 1, 0, -1, 1, 0, -1, 0};//E W S N

int arr[maxn];

string st;

char ss[4] = {'E', 'W', 'S', 'N'};

# if 01

struct node

{

    int x, y;

    int t;

    string str;

}s[maxn];

 

bool bfs()

{

    queue<node> q;

    struct node temp, front;

    front.x = sx;

    front.y = sy;

    front.t = 0;

    q.push(front);

    while(!q.empty())

    {

        temp = q.front();

        q.pop();

        if(temp.x == ex && temp.y == ey && temp.t < t)

        {

                t = temp.t;

                st = temp.str;

              //  cout <<temp.str << endl;

        }

        for(int i = 0; i < 4; i++)

        {

            int tx = temp.x + dis[i][0];

            int ty = temp.y + dis[i][1];

            if(str[tx][ty] == '#' || tx < 0 || tx >= n || ty < 0 ||ty >= m || temp.t + 1 >= t)

            {

                continue;

            }

            if(!vis[tx][ty])

            {

                vis[tx][ty] = true;

                front.x = tx;

                front.y = ty;

                front.t = temp.t + 1;

                front.str = temp.str + ss[i];

              //  cout << "tx = " << tx << "-- ty = " << ty << " "<< front.str << " ---" << ss[i]<< endl;

                q.push(front);

            }

        }

    }

    if(t != maxx)

    {

        return true;

    }

    return false;

}

# endif

# if 0

void dfs(int x, int y, int z)

{

    if(z >= t)

    {

        return ;

    }

    if(x == ex && y == ey && z < t)

    {

        t = z;

        for(int i = 0; i < z; i++)

        {

            arr[i] = brr[i];

        }

    }

    for(int i = 0; i < 4; i++)

    {

        int tx = x + dis[i][0];

        int ty = y + dis[i][1];

        if(str[tx][ty] == '#' || tx < 0 || tx >= n || ty < 0 ||ty >= m || z + 1 > t || vis[tx][ty])

        {

            continue;

        }

        vis[tx][ty] = true;

        brr[z] = i;

        dfs(tx, ty, z + 1);

        vis[tx][ty] = false;

    }

}

# endif

int main(int argc, char *argv[])

{

 

    while(cin >> n >> m)

    {

        t = maxx;

        memset(vis, false, sizeof(vis));

        for(int i = 0; i < n; i++)

        {

            cin >> str[i];

        }

        for(int i = 0; i < n; i++)

        {

            for(int j = 0; j < m; j++)

            {

 

                if(str[i][j] == 'E')

                {

                    ex = i;

                    ey = j;

                    str[i][j] = '.';

                }

                if(str[i][j] == 'S')

                {

                    sx = i;

                    sy = j;

                }

            }

        }

 

        bfs();

        if(t != maxx)

        cout << st<<endl;

        else

        {

            cout << "Can't eat it!" <<endl;

        }

    }

    return 0;

}

 

T题:

遇到相同的阵然后找一下转移一下

# include <iostream>

# include <queue>

# include <cstring>

# include <algorithm>

# include <string>

 

using namespace std;

 

const int maxn = 105;

const int maxx = 0x3f3f3f3f;

bool vis[maxn][maxn];

char str[maxn][maxn];

int n, m, t,sx, sy, ex,ey,dx,dy;

int dis[][2] = {0, 1, 0, -1, 1, 0, -1, 0};//E W S N

int arr[maxn];

int k;

string st;

char ss[4] = {'E', 'W', 'S', 'N'};

# if 01

struct node

{

    int x, y;

    int t;

}s[maxn];

 

bool f(char ch, int x,int y)

{

    for(int i = 0; i < n; i++)

    {

        for(int j = 0; j < m; j++)

        {

              if((i != x || y != j))

             {

              //   cout << "i = " << i<< " j = " << j << endl;

                    if(str[i][j] == ch )

                    {

 

                        dx = i,dy = j;

                        return true;

                    }

              }

 

        }

    }

    return false;

}

bool bfs()

{

    queue<node> q;

    struct node temp, front;

    front.x = sx;

    front.y = sy;

    front.t = 0;

    q.push(front);

    while(!q.empty())

    {

        temp = q.front();

        q.pop();

     //   cout << "temp.x = " << temp.x << "--- temp.y = " << temp.y << endl;

        if(temp.x == ex && temp.y == ey && temp.t < t)

        {

                t = temp.t;

              //  cout <<temp.str << endl;

        }

        for(int i = 0; i < 4; i++)

        {

            int tx = temp.x + dis[i][0];

            int ty = temp.y + dis[i][1];

            if(str[tx][ty] == '#' || tx < 0 || tx >= n || ty < 0 ||ty >= m || temp.t + 1 >= t)

            {

                continue;

            }

            if(!vis[tx][ty])

            {

                vis[tx][ty] = true;

 

                if(str[tx][ty] >= 'a' && str[tx][ty] <= 'z')

                {

                  //   cout << "tx = " << tx << " ty = " << ty  << " "<< str[tx][ty]<< endl;

                   if(f(str[tx][ty], tx, ty))

                    {

                        front.x = dx;

                        front.y = dy;

                      //  cout << "dx = " << dx << " dy = " << dy << endl;

                    }

                    else

                    {

                     //   cout << "false" << endl;

                        front.x = tx;

                        front.y = ty;

                    }

                }

                else

                {

                    front.x = tx;

                    front.y = ty;

                }

                front.t = temp.t + 1;

                q.push(front);

            }

        }

    }

    if(t != maxx)

    {

        return true;

    }

    return false;

}

# endif

int main(int argc, char *argv[])

{

    int k;

    while(cin >> k)

    {

        while(k--)

        {

            cin >> n >> m;

            {

                t = maxx;

                memset(vis, false, sizeof(vis));

                for(int i = 0; i < n; i++)

                {

                    cin >> str[i];

                }

                for(int i = 0; i < n; i++)

                {

                    for(int j = 0; j < m; j++)

                    {

 

                        if(str[i][j] == 'Q')

                        {

                            ex = i;

                            ey = j;

                            str[i][j] = '.';

                        }

                        if(str[i][j] == 'L')

                        {

                            sx = i;

                            sy = j;

                            vis[sx][sy] = true;

                        }

                    }

                }

 

                bfs();

                if(t != maxx)

                    cout << t<<endl;

                else

                {

                    cout << -1 <<endl;

                }

            }

        }

    }

 

    return 0;

}

 

 

U题:

1.能量在食物网中的流动是单向的,所以保证了这个图是一个有向无环图。

2.在这个图中没有入度的点就是生产者(不止一个),没有出度并且不是生产者的点就是 最高级消费者。

有一个要注意的地方就是生产者在那里,没有人吃是不算一条食物链的。食物链的条数事实上就是从生产者到最高级消费者 的路径总数。 

#include <cstdio>

#include <queue>

# include <iostream>

 

using namespace std;

 

const int MAXN = 2e5 + 7;

 

int n, m, ans, f[MAXN];

 

int read() {

    int x = 0, f = 1;

    char ch = getchar();

    while (ch > '9' || ch < '0') (ch == '-') && (f = -1), ch = getchar();

    while (ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();

    return x * f;

}

 

struct Edge;

struct Node {

    Edge *last;

    int in, out, ma;

    bool root;

} node[MAXN];

 

struct Edge {

    Node *from, *to;

    Edge *next;

    Edge(Node *from, Node *to) : from(from), to(to), next(from->last) {}

};

 

void addE(int x, int y) {

    node[x].last = new Edge(node + x, node + y);

    node[x].out++;

    node[y].in++;

}

 

queue<Node *> q;

 

 

int main() {

    n = read();

    m = read();

 

    for (int i = 1; i <= n; i++) node[i].ma = i;

 

    for (int i = 1; i <= m; i++) {

        int x = read(), y = read();

        addE(y, x);

    }

 

    for (int i = 1; i <= n; i++)  {

        if (!node[i].in && !node[i].out) continue;

        if (!node[i].in) f[i] = 1, q.push(node + i);

        if (!node[i].out && node[i].in) node[i].root = 1;

    }

 

    while (!q.empty()) {

        Node *v = q.front();

        q.pop();

 

        for (Edge *e = v->last; e; e = e->next) {

            f[e->to->ma] += f[v->ma];

            e->to->in--;

            if(!e->to->in) q.push(e->to);

        }

    }

 

    for (int i = 1; i <= n; i++) {

        if (node[i].root) ans += f[i];

    }

 

    printf("%d", ans);

 

    return 0;

}

 

V题:

跟c题一样改变了一下加一个时间统计

# include <iostream>

# include <queue>

# include <cstring>

 

using namespace std;

 

const int maxn = 205;

bool vis[maxn][maxn];

char str[maxn][maxn];

int n, m, t,sx, sy, ex,ey;

int dis[][2] = {0, 1, 0, -1, 1, 0, -1, 0};

 

# if 0

struct node

{

    int x, y, t;

};

 

bool bfs()

{

    queue<struct node> q;

    struct node temp, front;

    front.x = sx;

    front.y = sy;

    front.t = 0;

    q.push(front);

    while(!q.empty())

    {

        temp = q.front();

        q.pop();

        if(temp.x == ex && temp.y == ey && temp.t <= t)

        {

            return true;

        }

        for(int i = 0; i < 4; i++)

        {

            int tx = temp.x + dis[i][0];

            int ty = temp.y + dis[i][1];

            if(str[tx][ty] != '.' || tx < 0 || tx >= n || ty < 0 ||ty >= m || temp.t + 1 > t)

            {

                continue;

            }

            if(!vis[tx][ty])

            {

                vis[tx][ty] = 1;

                front.x = tx;

                front.y = ty;

                front.t = temp.t + 1;

                q.push(front);

            }

        }

    }

    return false;

}

 

# endif

# if 01

bool flag;

int minn;

void dfs(int x, int y, int z)

{

    if(flag)

    {

        return ;

    }

    if(x == ex && y == ey && z <= t)

    {

        flag = true;

        return ;

    }

    for(int i = 0; i < 4; i++)

    {

        int tx = x + dis[i][0];

        int ty = y + dis[i][1];

        if(str[tx][ty] != '.' || tx < 0 || tx >= n || ty < 0 ||ty >= m || z > t)

        {

            continue;

        }

        if(!vis[tx][ty])

        {

            vis[tx][ty] = true;

            dfs(tx, ty, z + 1);

            vis[tx][ty] = false;

        }

    }

}

 

# endif

int main(int argc, char *argv[])

{

    while(cin >> m >> n >> t, (m||n|| t))

    {

        flag = false;

        minn = 0x3f3f3f3f;

        memset(vis, false, sizeof(vis));

        for(int i = 0; i < n; i++)

        {

            cin >> str[i];

        }

        for(int i = 0; i < n; i++)

        {

            for(int j = 0; j < m; j++)

            {

                if(str[i][j] == 'S')

                {

                    sx = i;

                    sy = j;

                    vis[i][j] = true;

                }

                if(str[i][j] == 'P')

                {

                    str[i][j] = '.';

                    ex = i;

                    ey = j;

                }

            }

        }

        # if 0

        if(bfs())

        {

            cout << "YES" << endl;

        }

        else

        {

            cout << "NO" << endl;

        }

        # endif

        # if 01

        dfs(sx, sy, 0);

        if(flag)

        {

            cout << "YES" << endl;

        }

        else

        {

            cout << "NO" << endl;

        }

        # endif

 

    }

    return 0;

}

 

W题:

记录转弯bfs(),dfs()都可以。

# include <iostream>

# include <queue>

# include <cstring>

 

using namespace std;

 

const int maxn = 105;

bool vis[maxn][maxn];

char str[maxn][maxn];

int n, m, t,sx, sy, ex,ey;

int dis[][2] = {0, 1, 0, -1, 1, 0, -1, 0};

# if 01

bool flag;

void dfs(int x, int y, int z, int sum)

{

    if(flag)

    {

        return ;

    }

    if(x == ex && y == ey && sum <= t)

    {

        flag = true;

        return ;

    }

    for(int i = 0; i < 4; i++)

    {

        int tx = x + dis[i][0];

        int ty = y + dis[i][1];

        if(str[tx][ty] != '.' || tx < 0 || tx >= n || ty < 0 ||ty >= m || sum > t)

        {

            continue;

        }

        if(!vis[tx][ty])

        {

            vis[tx][ty] = true;

            if(z == -1 || z == i)

            {

                dfs(tx, ty, i, sum);

            }

            else if(z != i)

            {

                dfs(tx, ty, i, sum + 1);

            }

            vis[tx][ty] = false;

        }

    }

}

# endif

int main(int argc, char *argv[])

{

    int k;

    while(cin >> k)

    {

        while(k--)

        {

            cin >> n>> m >> t;

            {

                #  if 01

                flag = false;

                # endif

                memset(vis, false, sizeof(vis));

                for(int i = 0; i < n; i++)

                {

                    cin >> str[i];

                }

                for(int i = 0; i < n; i++)

                {

                    for(int j = 0; j < m; j++)

                    {

                        if(str[i][j] == 'S')

                        {

                            sx = i;

                            sy = j;

                        }

                        if(str[i][j] == 'P')

                        {

                            str[i][j] = '.';

                            ex = i;

                            ey = j;

                        }

                    }

                }

                

                # if 01

                dfs(sx, sy, -1, 0);

                if(flag)

                {

                    cout << "YES" << endl;

                }

                else

                {

                    cout << "NO" << endl;

                }

                # endif

 

            }

        }

    }

    return 0;

}

 

 

X题:

跟前面的R题一样,除了需要注意这次的r是有多个

# include <iostream>

# include <queue>

# include <cstring>

# include <algorithm>

 

using namespace std;

 

const int maxn = 205;

const int maxx = 0x3f3f3f3f;

bool vis[maxn][maxn];

char str[maxn][maxn];

int n, m, t,sx, sy, ex,ey;

int dis[][2] = {0, 1, 0, -1, 1, 0, -1, 0};

int num;

# if 01

struct node

{

    int x, y, t;

 

}s[maxn];

 bool operator<(const node a, const node b)

    {

        return a.t > b.t;

    }

bool bfs()

{

    priority_queue<node> q;

    struct node temp, f;

 

    for(int i = 0; i < num; i++)

    {

        f.x = s[i].x;

        f.y = s[i].y;

        f.t = 0;

        q.push(f);

    }

 

 

    while(!q.empty())

    {

        temp = q.top();

        q.pop();

        if(temp.x == ex && temp.y == ey && temp.t < t)

        {

                t = temp.t;

        }

        for(int i = 0; i < 4; i++)

        {

            int tx = temp.x + dis[i][0];

            int ty = temp.y + dis[i][1];

            if(str[tx][ty] == '#' || tx < 0 || tx >= n || ty < 0 ||ty >= m || temp.t + 1 >= t)

            {

                continue;

            }

            if(!vis[tx][ty])

            {

 

                vis[tx][ty] = 1;

                if(str[tx][ty] == 'x')

                {

                    f.t = temp.t + 2;

                }

                else

                {

                    f.t = temp.t + 1;

                }

                f.x = tx;

                f.y = ty;

                q.push(f);

            }

        }

    }

    if(t != maxx)

    {

        return true;

    }

    return false;

}

# endif

int main(int argc, char *argv[])

{

 

    while(cin >> n >> m)

    {

        t = maxx;

        num = 0;

        memset(vis, false, sizeof(vis));

 

        for(int i = 0; i < n; i++)

        {

            cin >> str[i];

        }

        for(int i = 0; i < n; i++)

        {

            for(int j = 0; j < m; j++)

            {

                if(str[i][j] == 'a')

                {

                    ex = i;

                    ey = j;

                    str[i][j] = '.';

                }

                if(str[i][j] == 'r')

                {

                    sx = i;

                    sy = j;

                     s[num].x = i;

                     s[num++].y = j;

 

                }

            }

        }

        bfs();

        if(t == maxx)

        {

            cout << "Poor ANGEL has to stay in the prison all her life." <<endl;

        }

        else

            cout << t << endl;

    }

 

    return 0;

}

Y题:

预处理一下狗有多条然后入队就行

# include <iostream>

# include <queue>

# include <cstring>

# include <algorithm>

 

using namespace std;

 

const int maxn = 205;

const int maxx = 0x3f3f3f3f;

bool vis[maxn][maxn];

char str[maxn][maxn];

int n, m, t,sx, sy, ex,ey;

int dis[][2] = {0, 1, 0, -1, 1, 0, -1, 0};

int num;

int c;

struct node

{

    int x, y;

 

}s[maxn];

 

 

 

bool bfs()

{

    queue<node> q;

    struct node temp, f;

 

    for(int i = 0; i < num; i++)

    {

        f.x = s[i].x;

        f.y = s[i].y;

        q.push(f);

    }

 

    while(!q.empty())

    {

        temp = q.front();

        q.pop();

 

        if(str[temp.x][temp.y] == 'p' )

        {

            c++;

        }

        for(int i = 0; i < 4; i++)

        {

            int tx = temp.x + dis[i][0];

            int ty = temp.y + dis[i][1];

 

            if(str[tx][ty] == '#' || tx < 0 || tx >= n || ty < 0 ||ty >= m)

            {

                continue;

            }

            if(!vis[tx][ty])

            {

                vis[tx][ty] = 1;

                f.x = tx;

                f.y = ty;

                q.push(f);

 

            }

        }

 

    }

    if(t != maxx)

    {

        return true;

    }

    return false;

}

 

 

int main(int argc, char *argv[])

{

 

    while(cin >> n >> m, (m||n))

    {

        t = maxx;

        num = 0;

        memset(vis, false, sizeof(vis));

        c = 0;

        for(int i = 0; i < n; i++)

        {

            cin >> str[i];

        }

        for(int i = 0; i < n; i++)

        {

            for(int j = 0; j < m; j++)

            {

 

                if(str[i][j] == 'd')//搜救犬

                {

                    sx = i;

                    sy = j;

                    s[num].x = i;

                    s[num++].y = j;

 

                }

            }

        }

        bfs();

        cout << c << endl;

    }

 

    return 0;

}

 

Z题:

让你输出广搜各个点到目标点的步数

# include <queue>

# include <cstring>

# include <algorithm>

 

using namespace std;

 

const int maxn = 205;

const int maxx = 0x3f3f3f3f;

bool vis[maxn][maxn];

int str[maxn][maxn];

int n, m, t,sx, sy, ex,ey;

int dis[][2] = {0, -1, 0, 1, 1, 0, -1, 0};

int num;

int c;

struct node

{

    int x, y, t;

 

};

 

 

 

bool bfs()

{

    queue<node> q;

    struct node temp, f;

    f.x = sx;

    f.y = sy;

    f.t = 0;

    q.push(f);

    while(!q.empty())

    {

        temp = q.front();

        q.pop();

 

        for(int i = 0; i < 4; i++)

        {

            int tx = temp.x + dis[i][0];

            int ty = temp.y + dis[i][1];

 

            if( tx < 1 || tx > n || ty < 1 ||ty > m)

            {

                continue;

            }

            if(!vis[tx][ty])

            {

                vis[tx][ty] = 1;

                f.x = tx;

                f.y = ty;

                f.t = temp.t + 1;

                q.push(f);

                str[tx][ty]= f.t;

            //    cout << "tx = " << tx << " ty = " << ty << " t = " << f.t <<endl;

            }

 

        }

 

 

    }

 

}

int main(int argc, char *argv[])

{

 

    while(cin >> n >> m >> sx >> sy)

    {

        memset(vis, false, sizeof(vis));

        memset(str, false, sizeof(str));

        vis[sx][sy] = true;

        bfs();

        for(int i = 1; i <= n; i++)

        {

            for(int j = 1; j <= m; j++)

            {

                cout << str[i][j];

            }

            cout << endl;

        }

    }

    return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值