zoukankan      html  css  js  c++  java
  • 山东省第六届ACM省赛

    ID.Title Hint
    A.Nias and Tug-of-War sort排序
    B.Lowest Unique Price set+map
    C.Game! 博弈
    D.Stars  
    E.BIGZHUGOD and His Friends I 赛瓦定理
    F.BIGZHUGOD and His Friends II 赛瓦定理 
    G.Cube Number 质因数分解
    H.Square Number 质因数分解
    I.Routing Table  
    J.Single Round Math 大数
    K.Last Hit  
    L.Circle of Friends 缩点

    A.Nias and Tug-of-War

    s.sort排序

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    
    struct node{
        double a;
        double b;
    }a[105];
    
    bool cmp(node a,node b){
        //if(a.a!=b.a)
        return a.a<b.a;//a升
        //return a.b>b.b;//b降
    }
    
    int main(){
    
        int T;
        int N;
        int i;
        double sum1,sum2;
    
        scanf("%d",&T);
    
        while(T--){
    
            scanf("%d",&N);
    
            for(i=0;i<N;++i){
                scanf("%lf%lf",&a[i].a,&a[i].b);
            }
    
            sort(a,a+N,cmp);
    
            sum1=0;
            for(i=0;i<N;i+=2){
                sum1+=a[i].b;
            }
            sum2=0;
            for(i=1;i<N;i+=2){
                sum2+=a[i].b;
            }
    
            if(sum1>sum2){
                printf("red
    ");
            }
            else if(sum2>sum1){
                printf("blue
    ");
            }
            else{//避免比较相等
                printf("fair
    ");
            }
        }
    
    
        return 0;
    }
    View Code

    B.Lowest Unique Price

    s.set+map

    #include<iostream>
    #include<stdio.h>
    #include<set>
    #include<map>
    using namespace std;
    
    int main(){
    
        int T;
        int N;
        char str[2];
        int x;
        int i;
        set<int> myset;
        map<int,int> mymap;
    
        scanf("%d",&T);
    
        while(T--){
    
            myset.clear();
            mymap.clear();
    
            scanf("%d",&N);
    
            for(i=0;i<N;++i){
                scanf("%1s",str);
    
                if(str[0]=='b'){
                    scanf("%d",&x);
                    myset.insert(x);
                    ++mymap[x];
                    if(mymap[x]>1){//多于一次价格x
                        myset.erase(x);
                    }
                }
                else if(str[0]=='c'){
                    scanf("%d",&x);
                    --mymap[x];
                    if(mymap[x]==0){//撤销一次没有价格x
                        myset.erase(x);
                    }
                    else if(mymap[x]==1){//撤销一次只剩一次价格x
                        myset.insert(x);
                    }
                }
                else{
                    if(!myset.empty()){
                        printf("%d
    ",*myset.begin());
                    }
                    else{
                        printf("none
    ");
                    }
                }
    
            }
    
        }
    
        return 0;
    }
    View Code

    C.Game!

    s.博弈。当石子个数大于2时,后手赢。

    还得看看博弈,做做题。

    #include<iostream>
    #include<stdio.h>
    using namespace std;
    
    int main(){
    
        int T;
        long long N;
    
        scanf("%d",&T);
    
        while(T--){
    
            scanf("%lld",&N);
    
            if(N>2){
                printf("blankcqk
    ");
            }
            else{
                printf("zbybr
    ");
            }
    
        }
    
        return 0;
    }
    View Code

    D.Stars

    E.BIGZHUGOD and His Friends I

    F.BIGZHUGOD and His Friends II

    G.Cube Number

    d.Given an array of distinct integers (a1, a2, ..., an), you need to find the number of pairs (ai, aj) that satisfy (ai * aj) is a cube number.

    s.和下个平方数类似,不错凑立方数的时候,不是从某个数中选2个数了,而是根据这个数的质因数的个数,把每个质因数凑成3个,这样可能直接用这个数乘上相应的数就行了。

    ps:long long,还有数组越界的判断搞了好久。。

    /*
    质因数分解
    */
    #include<iostream>
    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    using namespace std;
    
    const int MAXN=100;
    const long long MAXN2=1000000+10;//数字范围
    
    long long num[MAXN2];
    
    int factors[MAXN][2];//[0]存质因子,[1]存个数
    int factCnt;//不同的质因子总个数
    
    int getFactors(int n){
    
        int i,k;
        factCnt=0;
        for(i=2,k=sqrt(n);i<=k;++i){
            if(n%i==0){
                factors[factCnt][0]=i;
                factors[factCnt][1]=1;
                n=n/i;
                while(n%i==0){
                    ++factors[factCnt][1];
                    n=n/i;
                }
                ++factCnt;
                k=sqrt(n);//循环条件不直接写i<=sqrt(n);是因为这样可以避免重复开跟方
            }
        }
        if(n>1){
            factors[factCnt][0]=n;
            factors[factCnt][1]=1;
            ++factCnt;
        }
    
        int temp=1;
        int j;
        for(i=0;i<factCnt;++i){
            factors[i][1]=factors[i][1]%3;
            if(factors[i][1]!=0){
                for(j=0;j<factors[i][1];++j){
                    temp=temp*factors[i][0];
                }
            }
        }
        return temp;
    }
    
    int main(){
        int T;
        int N;
        int t;
        int i,j,k;
        long long ans;
        long long tmp;
        int temp;
        bool flag;
    
        scanf("%d",&T);
    
        while(T--){
            scanf("%d",&N);
            memset(num,0,sizeof(num));
            for(i=0;i<N;++i){
                scanf("%d",&t);
                if(t==1){
                    ++num[1];
                    continue;
                }
                temp=getFactors(t);
                ++num[temp];
            }
    
            ans=0;
            for(i=2;i<MAXN2;++i){
                if(num[i]!=0){
    
                    temp=getFactors(i);
    
                    tmp=1;
                    flag=true;
                    for(j=0;j<factCnt;++j){
                        for(k=0;k<3-factors[j][1];++k){
                            tmp=tmp*factors[j][0];
                            if(tmp>=MAXN2){
                                flag=false;
                                break;
                            }
                        }
                        if(flag==false){
                            break;
                        }
                    }
    
                    if(tmp>=MAXN2){
                        continue;
                    }
    
                    if(num[tmp]!=0){
                        ans=ans+num[i]*num[tmp];
                    }
                }
            }
    
            ans=ans/2;
            if(num[1]!=0){//1的时候特殊处理
                ans=ans+num[1]*(num[1]-1)/2;
            }
    
            printf("%lld
    ",ans);
        }
    
        return 0;
    }
    View Code

    H.Square Number

    d.Given an array of distinct integers (a1, a2, ..., an), you need to find the number of pairs (ai, aj) that satisfy (ai * aj) is a square number.

    s.质因数分解。如果某个质因子的个数为偶数,直接去掉;为奇数时保留一个。这样就缩小了规模。

    最后遍历一遍,如果某个数存在,那就从中选出2个就可构成一个平方数,这个数形成的平方数的总个数就是C(n,2)。

    /*
    质因数分解
    */
    #include<iostream>
    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    using namespace std;
    
    const int MAXN=102400;
    
    int factors[MAXN][2];//[0]存质因子,[1]存个数
    int factCnt;//不同的质因子总个数
    
    #define MAXN2 1000000+10
    int num[MAXN2];
    
    void getFactors(int n){
        int i,k;
        factCnt=0;
        for(i=2,k=sqrt(n);i<=k;++i){
            if(n%i==0){
                factors[factCnt][0]=i;
                factors[factCnt][1]=1;
                n=n/i;
                while(n%i==0){
                    ++factors[factCnt][1];
                    n=n/i;
                }
                ++factCnt;
                k=sqrt(n);//循环条件不直接写i<=sqrt(n);是因为这样可以避免重复开跟方
            }
        }
        if(n>1){
            factors[factCnt][0]=n;
            factors[factCnt][1]=1;
            ++factCnt;
        }
    
        int temp=1;
        for(i=0;i<factCnt;++i){
            factors[i][1]=factors[i][1]%2;
            if(factors[i][1]!=0){
                temp=temp*factors[i][0];
            }
        }
    
        ++num[temp];
    
    }
    
    
    
    int main(){
        /*
        int n;
        while(~scanf("%d",&n)){
    
            getFactors(n);
    
            printf("不同的质因子总个数:%d
    ",factCnt);
    
            int i,j;
            for(i=0;i<factCnt;++i){
                for(j=0;j<factors[i][1];++j){
                    printf("%d ",factors[i][0]);
                }
            }
    
            printf("
    ");
        }
        */
        int T;
        int N;
        int t;
        int i;
        int ans;
        int j;
    
        scanf("%d",&T);
    
        while(T--){
            scanf("%d",&N);
            memset(num,0,sizeof(num));
            for(i=0;i<N;++i){
                scanf("%d",&t);
                if(t==1){
                    ++num[1];
                    continue;
                }
                getFactors(t);
            }
    
            ans=0;
            for(i=0;i<MAXN2;++i){
    
                if(num[i]!=0){
                    //cout<<i<<" "<<num[i]<<endl;
                    ans=ans+(num[i]*(num[i]-1))/2;
                }
            }
    
            printf("%d
    ",ans);
        }
    
        return 0;
    }
    View Code

    c2.这个代码可以参考下。

    #include <stdio.h>
    #include <string.h>
    #define MAX 1000010
    int pri[1010];
    int dp[200];
    int vis[MAX];
    int amount=0;
    void init()
    {
        for(int i=2;i<=1000;i++)
        {//素数打表 
            for(int j=i+i;j<=1000;j+=i)
            {
                if(!pri[j])
                    pri[j]=1;
            }
        }
        //平方数打表 
        for(int i=2;i<=1000;i++)
            if(!pri[i])
                dp[amount++]=i*i;
    }
    
    int main()
    {
        int T,n;
        int t;
        int i,j;
        init();
        scanf("%d",&T);
        while(T--)
        {
            memset(vis,0,sizeof(vis));
            int ans=0;
            scanf("%d",&n);
            for(i=0;i<n;i++)
            {
                scanf("%d",&t);
                for(j=0;j<amount;j++)
                {
                    if(t%dp[j]==0)
                    {
                        while(t%dp[j]==0)
                            t/=dp[j];
                    }
                }
                ans+=vis[t];
                //除去平方因数后的值 ,有多少个该平方因数的值就可以组成多少对 
                vis[t]++;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

    I.Routing Table

    J.Single Round Math

    s.唯一比较坑的是N要等于M,然而并没从题意看出来。。

    c.java大数,注意类名要为Main

    import java.math.BigInteger;
    import java.util.Scanner;
    
    public class Main {//类名要用Main
        public static void main(String[] args){
            
            int T;
            BigInteger N,M;
            BigInteger MOD=new BigInteger("11");
            BigInteger ZERO=new BigInteger("0");
            Scanner sc=new Scanner(System.in);
            
            T=sc.nextInt();
            while((T--)>0){
                
                N=sc.nextBigInteger();
                M=sc.nextBigInteger();
                
                if(N.compareTo(M)==0&&N.mod(MOD).compareTo(ZERO)==0){//
                    System.out.println("YES");
                }
                else{//
                    System.out.println("NO");
                }
                
            }
            
        }
    }
    View Code

    K.Last Hit

    L.Circle of Friends

    d.

    s.强连通分量缩点

    ps:这里这个缩点方式可能有重边。

    我感觉用set可能解决重边的问题。

    另外缩点应该用桥来缩比较好。(好像发现是无向图有桥。。。)

    /*
    Tarjan算法
    复杂度O(N+M)
    */
    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    using namespace std;
    
    const int MAXN=100000+10;//点数
    const int MAXM=100000+10;//边数
    struct Edge{
        int to,next;
    }edge[MAXM];
    int head[MAXN],tot;
    int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];//Belong数组的值是1~scc
    int Index,top;
    int scc;//强连通分量的个数
    bool Instack[MAXN];
    int num[MAXN];//各个强连通分量包含点的个数,数组编号1~scc
    //num数组不一定需要,结合实际情况
    
    void addedge(int u,int v){
        edge[tot].to=v;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    void Tarjan(int u){
        int v;
        Low[u]=DFN[u]=++Index;
        Stack[top++]=u;
        Instack[u]=true;
        for(int i=head[u];i!=-1;i=edge[i].next){
            v=edge[i].to;
            if(!DFN[v]){
                Tarjan(v);
                if(Low[u]>Low[v])Low[u]=Low[v];
            }
            else if(Instack[v]&&Low[u]>DFN[v])
                Low[u]=DFN[v];
        }
        if(Low[u]==DFN[u]){
            scc++;
            do{
                v=Stack[--top];
                Instack[v]=false;
                Belong[v]=scc;
                num[scc]++;
            }
            while(v!=u);
        }
    }
    void solve(int N){
        memset(DFN,0,sizeof(DFN));
        memset(Instack,false,sizeof(Instack));
        memset(num,0,sizeof(num));
        Index=scc=top=0;
        for(int i=0;i<N;i++)
            if(!DFN[i])
                Tarjan(i);
    }
    void init(){
        tot=0;
        memset(head,-1,sizeof(head));
    }
    
    int N,M;
    struct Node{
        int u;
        int steps;
    };
    vector<int> g[MAXN];
    int ans;
    void bfs(){
        queue<Node> myQueue;
    
        Node tmp;
        tmp.u=Belong[0];
        tmp.steps=0;
    
        myQueue.push(tmp);
    
        Node u,v;
        int i;
    
        while(!myQueue.empty()){
    
            u=myQueue.front();
            myQueue.pop();
    
            if(u.u==Belong[N-1]){
                ans=u.steps;
                break;
            }
    
            for(i=0;i<g[u.u].size();++i){
                v.u=g[u.u][i];
                v.steps=u.steps+1;
                myQueue.push(v);
            }
        }
    }
    
    int main(){
    
        int T;
        //int N,M;
        int i,j;
        int u,v;
        int a,b;
        scanf("%d",&T);
    
        while(T--){
            init();
            scanf("%d%d",&N,&M);
            for(i=0;i<M;++i){
                scanf("%d%d",&u,&v);
                addedge(u,v);
            }
            solve(N);
    
            for(i=1;i<=scc;++i){
                g[i].clear();
            }
            for(i=0;i<N;++i){
                for(j=head[i];j!=-1;j=edge[j].next){
                    a=Belong[i];
                    b=Belong[edge[j].to];
                    if(a!=b){
    
                        g[a].push_back(b);
                    }
                }
            }
    
            ans=-1;
            bfs();
            printf("%d
    ",ans);
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    杨辉三角形
    open live writer
    已加载"C:WindowsSysWOW64msvcp120d.dll".无法查找或打开 PDB 文件.
    4.标准信号与槽
    python的单元测试unittest(一)
    python面向对象--类与对象
    python的文件操作与目录操作os模块
    Jenkins的安装与配置
    selenium切换到iframe
    selenium对富文本的操作
  • 原文地址:https://www.cnblogs.com/gongpixin/p/5327870.html
Copyright © 2011-2022 走看看