zoukankan      html  css  js  c++  java
  • GCPC 2018

    C、Coolest Ski Route

    题意:n个点,m条边组成的有向图,求任意两点之间的最长路径

    dfs记忆化搜索

    #include<iostream>
    #include<string.h>
    #include<string>
    #include<algorithm>
    #include<math.h>
    #include<string>
    #include<string.h>
    #include<vector>
    #include<utility>
    #include<map>
    #include<queue>
    #include<set>
    #define mx 0x3f3f3f3f
    #define ll long long
    using namespace std;
    int dis[1005],way[1005][1005],vis[1005],flag[1005];
    int n,m;
    int dfs(int x)
    {
        if(vis[x]==1)
            return dis[x];
        for(int i=1;i<=n;i++)
        {
            if(way[x][i]!=0)
                dis[x]=max(dis[x],dfs(i)+way[x][i]);//dis[x]表示以x为起点能走的最长路径是dis[x]
        }
        vis[x]=1;
        return dis[x];
    }
    int main()
    {
        cin>>n>>m;
        for(int i=0;i<m;i++)
        {
            int x,y,z;
            cin>>x>>y>>z;
            flag[y]=1;//标记终点
            if(way[x][y]!=0)
                way[x][y]=max(way[x][y],z);
            else
                way[x][y]=z;
        }
        int ans=0;
        for(int i=1;i<=n;i++)//枚举搜索起点
        {
            if(flag[i]==0)//给的是有向图,只能从有向图的起点开始搜索
                ans=max(ans,dfs(i));
        }
        cout<<ans<<endl;
        return 0;
    }
    /*
    5 5
    1 2 15
    2 3 12
    1 4 17
    4 2 11
    5 4 9
    
    6 6
    1 2 2
    4 5 2
    2 3 3
    1 3 2
    5 6 2
    1 2 4
    */

    Gym - 102021D:Down the Pyramid

    题意:给你一层数,让你求出它下面的一层数,上面的每一个数都是下层相邻两个数的和。(就像图中的数字金字塔一样)。问你下面一层有多少种满足的方案。

    思路:假设给出的值为,a1,a2,a3,a3...,假设下面的第一个数b0=x,那么可以推得第二个数b1=a1-x,第三个数就是a2-(a1-x),以此类推。其中bo...bn要满足的条件就是每一项都大于等于零。所以就可推得关于x 的不等式,所以就可以求出x的一个最小的范围,所以就可求出方案数。

    列出不等式,解x的范围

    b1=a1-x>=0                       x<=a1   

    b2=a2-(a1-x)>=0,              x>=a1-a2

    b3=a3-(a2-(a1-x))>=0       x<=a1-a2+a3

    b4=a4-a3+a2-a1+x>=0     x>=a1-a2+a3-a4

    奇数项<=的解取x得最小解

    偶数项>=得解取x得最大解

    #include<iostream>
    #include<string.h>
    #include<string>
    #include<algorithm>
    #include<math.h>
    #include<string>
    #include<string.h>
    #include<vector>
    #include<utility>
    #include<map>
    #include<queue>
    #include<set>
    #define mx 0x3f3f3f3f
    #define ll long long
    using namespace std;
    int n;
    int a[1000005];
    int main()
    {
        int cnt=0,num;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        int l=0,r=mx,ans=0;
        for(int i=1;i<=n;i++)
        {
            ans=a[i]-ans;
            if(i%2==1)
                r=min(r,ans);
            else
                l=max(l,-ans);
        }
        if(r>=l)
            printf("%d
    ",r-l+1);
        else
            printf("0
    ");
    }

     Gym - 102021E :Expired License

    题意:给你一对浮点数,让你判断这对浮点数的比值能否用一对素数的比值所表示,如果可以就输出两个素数。

    分析:首先将所给数转化成字符串处理(double转化成int数据会变化),两个数统一先乘以10^6化成整数,然后两数在除以他们的最大公因子判断是否为素数。其中里面包含一种特殊情况,就是当两数相等时,直接输出2,2

    #include<iostream>
    #include<string.h>
    #include<string>
    #include<algorithm>
    #include<math.h>
    #include<string>
    #include<string.h>
    #include<vector>
    #include<utility>
    #include<map>
    #include<queue>
    #include<set>
    #define mx 0x3f3f3f3f
    #define ll long long
    using namespace std;
    const int maxn = 1e7 + 10;
    int prim[maxn], w[maxn], cnt = 0;//prim[i]起标记作用,prim[i]==0表示i是质数
    int x[maxn];//x[i]表示偶数是i的符合条件的两个质数是x[i]和i-x[i];
    void init()
    {
        memset(prim, 0, sizeof(prim));
        for (int i = 2; i < maxn; i++)
        {
            if (prim[i]) //判断i是否为偶数
                continue;
            w[cnt++] = i;//w存质数
            for (int j = i << 1; j < maxn; j += i)//把所有质数的倍数标记
                prim[j] = 1;
        }
    
    }
    ll gcd(ll a, ll b)//最大公约数
    {
        return b == 0 ? a : gcd(b, a % b);
    }
    string s1,s2;
    int main()
    {
        int t;
        cin>>t;
        init();
        prim[1]=1;
        while(t--)
        {
            ll k1=0,k2=0,pos1=6,pos2=6;//先默认乘以10^6
            cin>>s1>>s2;
            int len1=s1.length();
            int len2=s2.length();
            for(int i=0;s1[i];i++)
            {
                if(s1[i]!='.')
                    k1=k1*10+(s1[i]-'0');
                else
                    pos1=len1-i-1;
            }
            for(int i=0;s2[i];i++)
            {
                if(s2[i]!='.')
                    k2=k2*10+(s2[i]-'0');
                else
                    pos2=len2-i-1;
            }
            while(pos1)
            {
                k1=k1*10;
                pos1--;
            }
            while(pos2)
            {
                k2=k2*10;
                pos2--;
            }
            if(k1==k2)
            {
                cout<<2<<' '<<2<<endl;
                continue;
            }
            ll temp=gcd(k1,k2);
            k1=k1/temp;
            k2=k2/temp;
        
            if(prim[k1]==0&&prim[k2]==0)
                cout<<k1<<' '<<k2<<endl;
            else
                cout<<"impossible"<<endl;
        }
        return 0;
    }

    Gym - 102021F :Fighting Monsters

    题意:给定N个怪兽,问能否选出两个怪兽,使得他们相互攻击,最后活着的怪兽剩1滴血,死的怪兽的血为零或者为负数。

    题解:找规律,看在给定的n个数中,是否存在一组相邻的斐波那契数

    #include<iostream>
    #include<string.h>
    #include<string>
    #include<algorithm>
    #include<math.h>
    #include<string>
    #include<string.h>
    #include<vector>
    #include<utility>
    #include<map>
    #include<queue>
    #include<set>
    #define mx 0x3f3f3f3f
    #define ll long long
    using namespace std;
    ll f[10000005],vis[1000006];//vis标记这个斐波那契数是否在n个数里面
    map<ll,ll>m;//标记是否是斐波那契数
    struct node
    {
        int x;
        int pos;
    }p[200005];
    bool cmp(node a,node b)
    {
        return a.x<b.x;
    }
    void feibo()
    {
        f[0]=0;
        f[1]=1,f[2]=2;
        m[1]=1,m[2]=2;
        for(int i=3;i<=10006;i++)
        {
            f[i]=f[i-1]+f[i-2];
            m[f[i]]=i;
            if(f[i]>=10000006)
                break;
        }
    }
    int main()
    {
        int n;
        feibo();
        // for(int i=0;f[i];i++)
        //     cout<<f[i]<<endl;
        scanf("%d",&n);
        int k=0;
        for(int i=1;i<=n;i++)
        {
            int temp;
            scanf("%d",&temp);
            if(vis[temp]!=0&&temp!=1)//要把重复得数去掉,斐波那契数是除1以外是没有重复的
                continue;
            vis[temp]=i;
            p[k].x=temp;
            p[k].pos=i;
            k++;
        }
        sort(p,p+k,cmp);
        int flag=0;
        for(int i=0;i<k;i++)
        {
            if(m[p[i].x]!=0)
            {
                int pos=m[p[i].x];
                if(p[i].x==p[i+1].x)
                {
                    cout<<p[i].pos<<' '<<p[i+1].pos<<endl;
                    flag=1;
                    break;
                }
                else if(vis[f[pos-1]])
                {
                    cout<<p[i].pos<<' '<<vis[f[pos-1]]<<endl;
                    flag=1;
                    break;
                }
                else if(vis[f[pos+1]])
                {
                    cout<<p[i].pos<<' '<<vis[f[pos+1]]<<endl;
                    flag=1;
                    break;
                }
            }
        }
        if(flag==0)
            cout<<"impossible"<<endl;
        return 0;   
    }
  • 相关阅读:
    如何装配vixta之一如何利用Nero将vixta刻录成ISO光盘
    48条经典的Windows小技巧
    再学 GDI+[85]: TGPImage(5) RotateFlip 旋转与镜像
    再学 GDI+[84]: TGPImage(4) 把图像显示在指定的矩形中
    再学 GDI+[83]: TGPImage(3) 平行四边形变换
    一个用 GDI+ 给图片添加花边的例子 给 "sky123" 做的
    再学 GDI+[82]: TGPImage(2) GetThumbnailImage 略缩图
    再学 GDI+[81]: TGPImage(1) 显示图像
    再学 GDI+[86]: TGPImage(6) 拖动图像
    再学 GDI+[88]: TGPImage(8) 放大镜
  • 原文地址:https://www.cnblogs.com/-citywall123/p/11360672.html
Copyright © 2011-2022 走看看