• ACM-ICPC 2018 沈阳赛区网络预赛


    A. Gudako and Ritsuka

    留坑

    B. Call of Accepted

    题意:给你一些运算,包括+-*()d,d的运算是2d6=2  和  2*6,然后输出最小值和最大值

    思路:按照题意模拟即可,可以用pair来存储最小值和最大值

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #include<map>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define eps 1e-10
    #define PI acos(-1.0)
    #define _e exp(1.0)
    #define ll long long
    const ll mod = 1e9+7;
    const int maxn = 1e5 + 5;
    int len;
    int fst[1005];
    char str[1005];
    
    pair<int,int> add(pair<int,int>p1,pair<int,int>p2)//加法
    {
        return make_pair(p1.first+p2.first,p1.second+p2.second);
    }
    pair<int,int> sub(pair<int,int>p1,pair<int,int>p2)//减法,小的是p1的小的减p2的大的,大的是p1的小的减p2的大的
    {
        return make_pair(p1.first-p2.second,p1.second-p2.first);
    }
    pair<int,int> mul(pair<int,int>p1,pair<int,int>p2)//乘法简单的不可行,可以把四种情况都取出来,然后比大小放进pair里
    {
        int t1=p1.first*p2.first;
        int t2=p1.first*p2.second;
        int t3=p1.second*p2.first;
        int t4=p1.second*p2.second;
        return make_pair(min(min(t1,t2),min(t3,t4)),max(max(t1,t2),max(t3,t4)));
    }
    pair<int,int> pp(pair<int,int>p1,pair<int,int>p2)//就是题目里的运算符d,p1是第一个数,p2是第一个数*第二个数
    {
        return make_pair(p1.first,p1.second*p2.second);
    }
    pair<int,int> judge(int begin,int end)
    {
        int i;
        pair<int,int> k;
        for(i=begin;i<=end;i++)
        {
            if(str[i]=='+' && fst[i]==fst[begin])
            {
                k=add(judge(begin,i-1),judge(i+1,end));
                return k;
            }
        }
        for(i=end;i>=begin;i--)
        {
            if(str[i]=='-' && fst[i]==fst[begin])
            {
                k=sub(judge(begin,i-1),judge(i+1,end));
                return k;
            }
        }
        for(i=begin;i<=end;i++)
        {
            if(str[i]=='*' && fst[i]==fst[begin])
            {
                k=mul(judge(begin,i-1),judge(i+1,end));
                return k;
            }
        }
        for(int i=end;i>=begin;i--)
        {
            if(str[i]=='d' && fst[i]==fst[begin])
            {
                k=pp(judge(begin,i-1),judge(i+1,end));
                return k;
            }
        }
        if(str[begin]=='(')
        {
            for(i=begin+1;fst[i]>=fst[begin+1];i++);
            k=judge(begin+1,i-1);
        }
        else
        {
            int n=0;
            for(int i=begin;i<=end;i++)
            {
                if(!(str[i]>='0' && str[i]<='9'))
                    break;
                n=n*10+str[i]-'0';
            }
            k=make_pair(n,n);
        }
        return k;
    }
    
    int main()
    {
        int i;
        while(cin>>str)
        {
            memset(fst,0,sizeof(fst));
            len=strlen(str);
            fst[0]=1;
            for(i=1;i<=len-1;i++)
            {
                if(str[i-1]=='(')
                    fst[i]=fst[i-1]+1;
                else if(str[i]==')')
                    fst[i]=fst[i-1]-1;
                else
                    fst[i]=fst[i-1];
            }
            pair<int,int> ans=judge(0,len-1);
            printf("%d %d
    ",ans.first,ans.second);
        }
        return 0;
    }
    View Code

    C. Convex Hull

    留坑

     D. Made In Heaven

    题意:求第k短路是否大于T

    思路:A*算法,启发式搜索

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define eps 1e-10
    #define PI acos(-1.0)
    #define _e exp(1.0)
    #define ll long long
    const int maxn=10010;
    const ll mod = 1e9 + 7;
    
    struct node
    {
        int to;
        int val;
        int next;
    };
    struct node2
    {
        int to;
        int g,f;
        bool operator<(const node2 &r) const
        {
            if(r.f==f)
                return r.g<g;
            return r.f<f;
        }
    };
    node edge[maxn],edge2[maxn];
    int n,m,s,t,k,cnt,cnt2,ans;
    int dis[1010],vis[1010],head[1010],head2[1010];
    void init()
    {
        memset(head,-1,sizeof(head));
        memset(head2,-1,sizeof(head2));
        cnt=cnt2=1;
    }
    void addedge(int from,int to,int val)
    {
        edge[cnt].to=to;
        edge[cnt].val=val;
        edge[cnt].next=head[from];
        head[from]=cnt++;
    }
    void addedge2(int from,int to,int val)
    {
        edge2[cnt2].to=to;
        edge2[cnt2].val=val;
        edge2[cnt2].next=head2[from];
        head2[from]=cnt2++;
    }
    bool spfa(int s,int n,int head[],node edge[],int dist[])
    {
        queue<int>que;
        int inq[1010];
        for(int i=0;i<=n;i++)
        {
            dis[i]=INF;
            inq[i]=0;
        }
        dis[s]=0;
        que.push(s);
        inq[s]++;
        while(!que.empty())
        {
            int q=que.front();
            que.pop();
            inq[q]--;
            if(inq[q]>n)
                return false;
            int k=head[q];
            while(k>=0)
            {
                if(dist[edge[k].to]>dist[q]+edge[k].val)
                {
                    dist[edge[k].to]=edge[k].val+dist[q];
                    if(!inq[edge[k].to])
                    {
                        inq[edge[k].to]++;
                        que.push(edge[k].to);
                    }
                }
                k=edge[k].next;
            }
        }
        return true;
    }
    int T;
    bool A_star(int s,int t,int n,int k,int head[],node edge[],int dist[])
    {
        node2 e,ne;
        int cnt=0;
        priority_queue<node2>que;
        if(s==t)
            k++;
        if(dis[s]==INF)
            return false;
        e.to=s;
        e.g=0;
        e.f=e.g+dis[e.to];
        que.push(e);
        while(!que.empty())
        {
            e=que.top();
            que.pop();
            if(e.to==t)
                cnt++;
            if(cnt==k)
                return e.g<=T;
            for(int i=head[e.to];i!=-1;i=edge[i].next)
            {
                ne.to=edge[i].to;
                ne.g=e.g+edge[i].val;
                ne.f=ne.g+dis[ne.to];
                if(ne.g>T)
                    continue;
                que.push(ne);
            }
    
        }
        return false;
    
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            scanf("%d%d%d",&s,&t,&k);
            scanf("%d",&T);
            init();
            for(int i=1;i<=m;i++)
            {
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
                addedge(a,b,c);
                addedge2(b,a,c);
            }
            spfa(t,n,head2,edge2,dis);
            if(!A_star(s,t,n,k,head,edge,dis))
                puts("Whitesnake!");
            else
                puts("yareyaredawa");
        }
        return 0;
    }
    View Code

    E. The cake is a lie

    留坑

    F. Fantastic Graph

    题意:

     一个二分图,左边有n个点,右边有m个点,一共有k条边分别连接左右两个点,问能否取这k条边中部分边,使得所有点的度数都在l~r范围内。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #include<map>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define eps 1e-10
    #define PI acos(-1.0)
    #define _e exp(1.0)
    #define ll long long
    const ll mod = 1e9+7;
    const int maxn = 1e5 + 5;
    const  int MAXN=10010;
    const int MAXM=40010;
    struct edge
    {
        int to,next,cap,flow;
    }edge[MAXM];
    int tol;
    int head[MAXN];
    int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];
    void init()
    {
        tol=0;
        memset(head,-1,sizeof(head));
    }
    void addedge(int u,int v,int w,int rw=0)
    {
        edge[tol].to=v;edge[tol].cap=w;edge[tol].next=head[u];
        edge[tol].flow=0;head[u]=tol++;
        edge[tol].to=u;edge[tol].cap=rw;edge[tol].next=head[v];
        edge[tol].flow=0;head[v]=tol++;
    }
    int sap(int start,int end,int N)
    {
        memset(gap,0,sizeof(gap));
        memset(dep,0,sizeof(dep));
        memcpy(cur,head,sizeof(head));
        int u=start;
        pre[u]=-1;
        gap[0]=N;
        int ans=0;
        while(dep[start]<N)
        {
            if(u==end)
            {
              int Min=INF;
              for(int i=pre[u];i!=-1;i=pre[edge[i^1].to])
                 if(Min>edge[i].cap-edge[i].flow)
                     Min=edge[i].cap-edge[i].flow;
             for(int i=pre[u];i!=-1;i=pre[edge[i^1].to])
             {
                 edge[i].flow+=Min;
                 edge[i^1].flow-=Min;
             }
             u=start;
             ans+=Min;
            continue;
        }
        bool flag=false;
        int v;
        for(int i=cur[u];i!=-1;i=edge[i].next)
        {
            v=edge[i].to;
            if(edge[i].cap-edge[i].flow && dep[v]+1 == dep[u])
            {
                flag=true;
                cur[u]=pre[v]=i;
                break;
            }
        }
        if(flag)
        {
            u=v;
            continue;
        }
        int Min=N;
        for(int i=head[u];i!=-1;i=edge[i].next)
            if(edge[i].cap-edge[i].flow && dep[edge[i].to]<Min)
            {
                Min=dep[edge[i].to];
                cur[u]=i;
            }
        gap[dep[u]]--;
        if(!gap[dep[u]])
            return ans;
        dep[u]=Min+1;
        gap[dep[u]]++;
        if(u!=start )
            u=edge[pre[u]^1].to;
        }
        return ans;
    }
    int S,T;
    vector<int>ee;
    void add(int u,int v,int low,int high)
    {
        addedge(u,v,high-low);
        if(low>0)
        {
            addedge(S, v, low);
            ee.push_back(tol-2);
            addedge(u, T, low);
            ee.push_back(tol-2);
        }
    }
    bool check()
    {
        for(int i=0;i<ee.size();i++)
        {
            int e=ee[i];
            if(edge[e].flow !=edge[e].cap)
                return false;
        }
        return true;
    }
    
    int main()
    {
        int N,M,K;
        int ca=0;
        while(scanf("%d%d%d",&N,&M,&K)==3)
        {
            ee.clear();
            ca++;
            int L,R;
            scanf("%d%d",&L,&R);
            init();
            S=N+M+2;
            T=N+M+3;
            for(int i=1;i<=N;i++)
                add(0,i,L,R);
            for(int i=N+1;i<=N+M;i++)
                add(i, N+M+1, L, R);
            int u,v;
            while(K--)
            {
                scanf("%d%d",&u,&v);
                addedge(u, v+N, 1);
            }
            addedge(N+M+1, 0, INF);
            sap(S,T,T+1);
            if(check())
                printf("Case %d: Yes
    ",ca);
            else
                printf("Case %d: No
    ",ca);
        }
        return 0;
    }
    View Code

    G. Spare Tire

    题意:给定1<=i<=n ; 要求i与m互质,求出i*i+i的累积总和

    思路:

    由a的递推式可以很容易地得到ai=i*(i+1)

    求所有满足条件的数不好求,我们可以用所有的减去不满足条件的,即与m不互素的数贡献的a值

    根据算数基本定理将m分解,与m不互素的就是至少有其中一个因子,算所有的所以要容斥

    对于每个因子积sum,会形成sum,2*sum,3*sum...[n/sum]*sum这些不互素的数,

    设k=[n/sum]

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #include<map>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define eps 1e-10
    #define PI acos(-1.0)
    #define _e exp(1.0)
    #define ll long long
    const ll mod = 1e9+7;
    const int maxn = 1e5 + 5;
    ll prime[10100];
    int pl=0;
    bool vis[10010];
    ll n,m;
    void getprime()
    {
        for(ll i=2;i<10010;i++)
        {
            if(vis[i]==false)
            {
                prime[++pl]=i;
            }
            for(int j=1;j<pl && i*prime[j]<10010;j++)
            {
                vis[i*prime[j]]=true;
                if(i % prime[j]==0)
                    break;
            }
        }
    }
    ll num[15];
    int tot;
    void bre(ll n)
    {
        tot=0;
        for(int i=1;i<pl && prime[i]*prime[i]<=n;i++)
        {
            if(n%prime[i]==0)
            {
                num[tot++]=prime[i];
                while(n%prime[i]==0)
                {
                    n/=prime[i];
                }
            }
            if(n==1)
                break;
        }
        if(n!=1)
            num[tot++]=n;
    }
    ll inv2,inv3,inv6;
    ll fpow(ll a,ll b)
    {
        ll ans=1;
        ll tmp=a%mod;
        while(b)
        {
            if(b&1)
                ans=ans*tmp%mod;
            tmp=tmp*tmp%mod;
            b/=2;
        }
        return ans;
    }
    void solve()
    {
        ll ans=0;
        for(int i=0;i<(1<<tot);i++)
        {
            int cnt=0;
            ll sum=1;
            for(int j=0;j<tot;j++)
            {
                if(i&(1<<j))
                {
                    cnt++;
                    sum*=num[j];
                }
            }
            ll k=n/sum;
            sum%=mod;
            ll p=(1+k)*k%mod*inv2%mod*sum%mod;
            ll q=k*(1+k)%mod*(2*k+1)%mod*inv6%mod*sum%mod*sum%mod;
            if(cnt&1)
            {
                ans-=p;
                if(ans<0)
                    ans+=mod;
                ans-=q;
                if(ans<0)
                    ans+=mod;
            }
            else
            {
                ans=(ans+p);
                if(ans>mod)
                    ans-=mod;
                ans+=q;
                if(ans>mod)
                    ans-=mod;
            }
        }
        printf("%lld
    ",ans);
    }
    int main()
    {
        getprime();
        inv2=fpow(2,mod-2);
        inv6=fpow(6,mod-2);
        while(~scanf("%lld%lld",&n,&m))
        {
            bre(m);
            solve();
        }
    }
    View Code

    H. Hamming Weight

    留坑

    I. Lattice's basics in digital electronics

    题意:给出一个映射关系左为ascll值,右为密码,然后给出一个16进制的数,要求先将16进制转化为2进制然后每9位通过奇偶校验判断,若前8位有奇数个1并且第9位为0则通过奇偶校验,若前8位有偶数个1且第9 位为1也通过奇偶校验。取出的串在映射中进行查找,输出对应ascll值的字符。

    思路:可以用map来找取编码对应的值,网上好像也有人用字典树的,应该都可以的吧,然后奇偶校验可以用异或值来进行判断。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #include<map>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define eps 1e-10
    #define PI acos(-1.0)
    #define _e exp(1.0)
    #define ll long long
    const int maxn = 1e5 + 5;
    map<string,int>mp;
    char str[200010];
    int a[1000010];
    int b[1000010];
    char ss[20];
    
    int getV(char ch)
    {
        if(ch>='A' && ch<='Z')
            return ch-'A'+10;
        if(ch>='a' && ch<='z')
            return ch-'a'+10;
        else
            return ch-'0';
    }
    int main()
    {
        int T;
        int M,N;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&M,&N);
            int v;
            mp.clear();
            string sss;
            while(N--)
            {
                scanf("%d",&v);
                cin>>sss;
                mp[sss]=v;     //将二进制与对应的ascll码对应
            }
            scanf("%s",str);
            int len=strlen(str);
            int cnta=0;
            for(int i=0;i<len;i++)
            {
                int v=getV(str[i]);
                a[cnta++]=v/8%2;
                a[cnta++]=v/4%2;
                a[cnta++]=v/2%2;
                a[cnta++]=v/1%2;      //十六进制转化为二进制
            }
            int cntb=0;
            for(int i=0;i+9<=cnta;i+=9)
            {
                int tmp=0;
                for(int j=0;j<9;j++)   //取异或值来验证奇偶校验
                    tmp^=a[i+j];
                if(!tmp)
                    continue;
                for(int j=0;j<8;j++)     //放入b数组
                    b[cntb++]=a[i+j];
            }
            string now="";
            for(int i=0;i<cntb;i++)
            {
                if(M==0)
                    break;
                now+=(char)(b[i]+'0');   //把b数组转换为char类型的
                if(mp.count(now))
                {
                    printf("%c",mp[now]);     //如果有存在的已经定义好的编码就输出
                    M--;
                    if(M==0)
                        break;
                    now="";
                }
            }
            printf("
    ");
        }
        return 0;
    }
    View Code

    J. Ka Chang

    留坑

    K. Supreme Number

    题意:输出小于等于n的超级质数,超级质数是它的任何子序列都是质数。

    思路:比赛的时候一开始看成字串找了好久的bug。考虑到答案中任意一位都必须是1或质数,可知答案只可能由1、2、3、5、7构成。由于任意两个不为1的数字构成 的两位数一定可以被11整除,所以答案中除1外的数字只能出现一次;1最多出现2次,因为111可以被3整除;而2、5、7三者一定不会有两者同时出现。因此满足条件的整数不会超过四位,全部预处理出来即可。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define eps 1e-10
    #define PI acos(-1.0)
    #define _e exp(1.0)
    #define ll long long
    const int maxn=50;
    const ll mod = 1e9 + 7;
    
    int a[]={1,2,3,5,7,11,13,17,23,31,37,53,71,73,113,131,137,173,311,317};
    int main()
    {
        int t;
        int ca=1;
        scanf("%d",&t);
        while(t--)
        {
            int ans;
            char str[105];
            scanf("%s",str);
            if(strlen(str)>=5)
                ans=317;
            else
            {
                int num=0;
                num=atoi(str);
                for(int i=0;i<20;i++)
                {
                    if(num>=317)
                    {
                        ans=317;
                        break;
                    }
                    else if(num<a[i] && num<317)
                    {
                        ans=a[i-1];
                        break;
                    }
                }
            }
            printf("Case #%d: %d
    ",ca++,ans);
        }
    }
    View Code
  • 相关阅读:
    [网络技术][转]网卡的offload概念
    [网络技术][转]路由表查找过程(ip_route_input_slow)
    [linux-内核][转]内核日志及printk结构浅析
    [DPDK][转]DPDK编程开发(4)—lcore
    [技术新闻]相关网站
    [计算机、网络相关历史]unix简史
    [编辑器]sublime使用入门
    [CDN]CDN的系统架构
    [windows操作系统]windows管理
    [安卓]创建一个视图类
  • 原文地址:https://www.cnblogs.com/smallhester/p/9610304.html
Copyright © 2020-2023  润新知