• 20190825


    期望: 60 + 30 + 20 = 110.实际: 40 + 0 + 10 = 50.

    T1:给定一个正整数 M ,找出有多少不同的正整数对 (x, y) 使得存在正整数 p 和 q,满足下面这个方程:p*x2 + q*y = M.

    S1:开局以为是数学题,套某个定理,想不到打了暴力,不知到>500的点为什么错了.后面跟dalao讨论,发现枚举的顺序有问题,导致TLE与WA.对于60pts,正确的打开方式应该为先枚举x( x<=sqrt ( m ) ),再枚举y( y<=m ),再枚举p.(p*x*x<m),一旦枚举到p,使x,y成立,就break.看上去o(n^3),其实为o(能过60pts).正解其实为暴力的优化,我们将p放在第二维枚举,第三维不枚举j,直接枚举m-x*x*p的因子,合法的y一定在其中,这样o(能过100pts)就解决了.

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    using namespace std;
    #define re register
    int T,m,ans,vis[200010];
    vector<int> v[200010];
    inline int fd(){
        int s=1,t=0;
        char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')
                s=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9'){
            t=t*10+c-'0';
            c=getchar();
        }
        return s*t;
    }
    void work()
    {
        for(re int i=1;i<=200000;++i)
            for(re int j=1;j*i<=200000;++j)
                v[i*j].push_back(i);
    }
    int main()
    {
        freopen("pairs.in","r",stdin);
        freopen("pairs.out","w",stdout);
        T=fd(),work();
        while(T--){
            m=fd();
            ans=0;
            for(re int x=1;x*x<=m;++x){
                for(re int p=1;p*x*x<m;++p){
                    int cnt=v[m-x*x*p].size();
                    for(re int k=0;k<cnt;++k)
                        if(!vis[v[m-x*x*p][k]]){
                            ++ans;
                            vis[v[m-x*x*p][k]]=1;
                        }
                }
                for(re int p=1;p*x*x<m;++p){
                    int cnt=v[m-x*x*p].size();
                    for(re int k=0;k<cnt;++k)
                        vis[v[m-x*x*p][k]]=0;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }

    T2:幼儿园老师正在给小朋友们排座位.一共有 N 个小朋友, M 个座位.为了尽量让小朋友分到自己喜欢的座位上去,决定让每个小朋友都选出两个自己最想坐的位置.小朋友们选好之后,老师却犯愁了.老师现在想知道,一共有多少种安排座位的方式能满足所有小朋友的意愿?由于答案可能很大,你需要将其对 10000019 取模后输出.

    S2:显然30pts用于dfs,但是题目说明了小朋友选的两个座位可能是一样的,选择这两个座位的方案只算一种,在dfs要判重(30pts - > 0 pts).正解:考虑将座位看成点,小朋友喜欢的两个座位连一条双向边.我们要做的是将边定向.规定a-->b为选b,b-->a为选a.在一个n个点,m条边的联通块内,考虑以下几种情况:①:n<m,座位小于人数,显然无解.②:n-1==m.将每一个点做为根,都会使每一条边得到唯一方向,所以有n种方案.③:n==m,无自环.显然顺逆时针,两种方案.④:n==m,有自环,自环的两点选择唯一确定,全局方案唯一.最后利用乘法原理,将每个连通块的方案相乘即为ans.

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define re register
    const int mod=10000019;
    const int maxn=200010*10+10;
    int T,n,m,cnt,ans,vis[maxn],sum[maxn],head[maxn];
    struct bian{
        int next,to;
    }len[maxn<<1];
    inline int fd(){
        int s=1,t=0;
        char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')
                s=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9'){
            t=t*10+c-'0';
            c=getchar();
        }
        return s*t;
    }
    void add(int from,int to){
        len[++cnt].to=to;
        len[cnt].next=head[from];
        head[from]=cnt;
    }
    void dfs(int x,int &n,int &m,int &flag){
        if(vis[x]) return;
        vis[x]=1;
        ++n,m+=sum[x];
        for(re int k=head[x];k;k=len[k].next){
            int to=len[k].to;
            if(to==x) flag=1;
            dfs(to,n,m,flag);
        }
    }
    int work(int x){
        int n=0,m=0,flag=0;
        dfs(x,n,m,flag);
        m/=2;
        if(m>n) return 0;
        if(flag) return 1;
        if(n==m) return 2;
        return n; 
    }
    int main()
    {
        freopen("seat.in","r",stdin);
        freopen("seat.out","w",stdout);
        T=fd();
        while(T--){
            n=fd(),m=fd();
            memset(head,0,sizeof(head));
            memset(vis,0,sizeof(vis));
            memset(sum,0,sizeof(sum));
            for(re int i=1;i<=n;++i){
                int from=fd(),to=fd();
                add(from,to),add(to,from);
                ++sum[from],++sum[to];
            }
            ans=1;
            for(re int i=1;i<=m;++i)
                if(!vis[i])
                    ans=1ll*ans*work(i)%mod;
            printf("%d
    ",ans);
        }
        return 0;
    }

    T3:给定一个整数 N ,请你计算 (7 +4√3 ) N 的整数部分模 1000000007 后的结果.

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define e exit(0)
    #define re register
    const int mod=1000000007;
    int T,n,ans;
    inline int fd(){
        int s=1,t=0;
        char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')
                s=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9'){
            t=t*10+c-'0';
            c=getchar();
        }
        return s*t;
    }
    struct jz{
        int a[5][5];
        jz(){memset(a,0,sizeof(a));}
        jz operator*(const jz &p){
            jz ans;
            for(re int k=1;k<=2;++k)
                for(re int i=1;i<=2;++i)
                    for(re int j=1;j<=2;++j)
                        ans.a[i][j]=(ans.a[i][j]%mod+1ll*a[i][k]*p.a[k][j]%mod)%mod;
            return ans;
        }
    };
    jz work(){
        jz g;
        g.a[1][1]=7,g.a[1][2]=4;
        g.a[2][1]=12,g.a[2][2]=7;
        return g;
    }
    jz qsm(jz k,int y){
        jz ans;
        for(re int i=1;i<=2;++i)
            ans.a[i][i]=1;
        while(y){
            if(y&1) ans=ans*k;
            k=k*k;
            y>>=1;
        }
        return ans;
    }
    int main()
    {
        freopen("math.in","r",stdin);
        freopen("math.out","w",stdout);
        T=fd();
        while(T--){    
            n=fd();
            if(n==0){
                printf("1
    ");
                continue;
            }
            else if(n==1){
                printf("13
    ");
                continue;
            }
            jz k=work();
            k=qsm(k,n-1);
            ans=(1ll*7*k.a[1][1]%mod+1ll*4*k.a[2][1]%mod)%mod;
            ans=(1ll*2*ans%mod-1%mod)%mod;
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    【WPF】【基础】布局系统
    【设计】【托管扩展性框架】 MEF vs 2010 samples
    【wpf】【控件】内容控件
    【Wpf】【debug】Exception has been thrown by the target of an invocation.
    【设计模式】概述
    期待与悲催中的2012
    金额转为大写人民币
    使用vs2005的GridView控件,菜鸟问题。
    Microsoft Visual Studio 2005中使用水晶报表
    将金额小写转化成汉字大写(javascript)
  • 原文地址:https://www.cnblogs.com/xqysckt/p/11410709.html
Copyright © 2020-2023  润新知