zoukankan      html  css  js  c++  java
  • ICPC小米网络赛第一场

    A     Intelligent Warehouse

    dp,筛出来所有的素数,然后再枚举所有的素数,由于约数个数定理,我们总能把与之成倍数关系的情况都累加起来。

    #include <bits/stdc++.h>
    #define debug freopen("r.txt","r",stdin)
    #define mp make_pair
    #define ri register int
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef double lf;
    typedef pair<ll, ll> pii;
    const int maxn = 1e7+1;
    const ll INF = 1e18;
    const int mod = 1e9+7;
    const double eps=1e-6;
    const double PI=acos(-1.0);
    inline ll read(){ll s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*w;}
    ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
    int ip[maxn],i,n,p[maxn],cnt,dis[maxn],a[maxn],ans,x,dp[maxn],j;
    bool vis[maxn];
    void get_prime()
    {
        memset(vis,0,sizeof(vis));
        vis[1]=1;
        p[1]=1;
        ip[1]=1;
        cnt=1;
        for (int i=2;i<=maxn;i++)
        {
            if(!vis[i]) 
            {
                cnt++;
                p[cnt]=i;
                ip[i]=cnt;
            }
            for (int j=1;j<=cnt && i*p[j]<=maxn;j++)
            {
                vis[i*p[j]]=1;
            }
        }
    }
    int main()
    {
        get_prime();
        n=read();
        for (i=1;i<=n;i++)
        {
            x=read();
            a[x]++;
        }
        for (i=1;i<maxn;i++)
        {
            dp[i]+=a[i];
            ans=max(ans,dp[i]);
            for (j=1;j<=cnt&& p[j]*i<maxn;j++)
                dp[p[j]*i]=max(dp[p[j]*i],dp[i]);
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    B     Intelligent Robot

    计算几何

    题目要求只能沿着墙走,换而言之,对我们有用的,只有点与点之间的直线路径对我们有用,所以只需判断两点之间是否不被墙挡,再计算距离,跑最短路即可。

    判断两点之间是否不被墙挡=线段之间是否相交

    #include <bits/stdc++.h>
    #define debug freopen("r.txt","r",stdin)
    #define mp make_pair
    #define ri register int
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef double lf;
    typedef pair<ll, ll> pii;
    const int maxn =1e5+10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9+7;
    const double eps=1e-6;
    const double PI=acos(-1.0);
    inline ll read(){ll s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*w;}
    ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
    struct vec{
        lf x,y;
        vec(lf x=0,lf y=0):x(x),y(y){}
        vec operator-(const vec &b){return vec(x-b.x,y-b.y);}
        vec operator+(const vec &b){return vec(x+b.x,y+b.y);}
        vec operator*(lf k){return vec(k*x,k*y);}
        lf operator ^(const vec &b){return x*b.y-y*b.x;}
        lf len(){return hypot(x,y);}
        lf sqr(){return x*x+y*y;}
        /*截取*/vec trunc(lf k=1){return *this*(k/len());}
        /*逆时针旋转*/vec rotate(double th){lf c=cos(th),s=sin(th); return vec(x*c-y*s,x*s+y*c);}
    }p[maxn],s,t;
    lf cross(vec a,vec b){return a.x*b.y-a.y*b.x;};
    lf cross(vec a,vec b,vec c){return cross(a-b,b-c);}
    lf dot(vec a,vec b){return a.x*b.x+a.y*b.y;}
    bool cmp_xy(const vec &a,const vec &b){return make_pair(a.x,a.y)<make_pair(b.x,b.y);}
    bool cmp_atan(const vec &a,const vec &b){return atan2(a.x,a.y)<atan2(b.x,b.y);}
    /*输出*/ostream &operator<<(ostream &o,const vec &v){return o<<'('<<v.x<<','<<v.y<<')';}
    struct node{
        int to; lf dis;
        bool operator<(const node &b)const{
            return dis>b.dis;
        }
    };
    int n,m,k,i,j,flag,q;
    lf x,y;
    bool vis[maxn];
    vector<node> G[maxn];
    lf dis[maxn];
    void dij(int s,int n){ //s是起点,dis是结果
        fill(vis,vis+n+1,0);
        fill(dis,dis+n+1,INF); dis[s]=0; //last[s]=-1;
        static priority_queue<node> q; 
        q.push({s,0});
        while(!q.empty()){
            int x=q.top().to; q.pop();
            if(vis[x])continue; vis[x]=1;
            for(auto i:G[x]){
                int p=i.to;
                if(dis[p]>dis[x]+i.dis){
                    dis[p]=dis[x]+i.dis;
                    q.push({p,dis[p]});
                }
            }
        }
    }
    bool judge(vec a,vec b,vec c,vec d){ //线段ab和线段cd
        #define SJ(x) max(a.x,b.x)<min(c.x,d.x)
        || max(c.x,d.x)<min(a.x,b.x)
        if(SJ(x) || SJ(y))return 0;
        #define SJ2(a,b,c,d) cross(a-b,a-c)*cross(a-b,a-d)<0
        return SJ2(a,b,c,d) && SJ2(c,d,a,b);
    }
    int main()
    {
        n=read(),m=read(),k=read();
        for (i=1;i<=k;i++) 
        {
            scanf("%lf%lf",&x,&y);
            p[i]=vec(x,y);
            scanf("%lf%lf",&x,&y);
            p[i+k]=vec(x,y);
        }
        scanf("%lf%lf",&x,&y);
        p[0]=vec(x,y);
        scanf("%lf%lf",&x,&y);
        p[2*k+1]=vec(x,y);
        for (i=0;i<=2*k+1;i++)
        {
            for (j=i+1;j<=2*k+1;j++)
            {
                flag=1;
                for (q=1;q<=k;q++)
                    if (judge(p[i],p[j],p[q],p[q+k]))
                    {
                        flag=0;
                        break;
                    }
                if (flag)
                {
                    G[i].pb({j,(p[i]-p[j]).len()});
                    G[j].pb({i,(p[i]-p[j]).len()});
                }
            }
        }
        dij(0,2*k+1);
        printf("%.4f
    ", dis[2*k+1]);
        return 0;
    }
    View Code

    C     Smart Browser

    水题

    D     Router Mesh

    在求割点的模板中,如果low[v]>=low[u],cut[u]=true则说明u是割点,那么改成cut[u]++,说明去掉u点会多形成cut[u]个连通图

    假设u是根节点

    1.cut[u]=0 说明u为孤立点 则去掉后连通数少1

    2.cut[u]=1 说明u只有一个儿子 则去掉后连通数不变

    3.cut[u]>=2 说明u有>=2个儿子 则去掉后连通数多cut[u]-1

    #include <bits/stdc++.h>
    #define debug freopen("r.txt","r",stdin)
    #define mp make_pair
    #define ri register int
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef double lf;
    typedef pair<ll, ll> pii;
    const int maxn = 1e6+10;
    const ll INF = 1e18;
    const int mod = 1e9+7;
    const double eps=1e-6;
    const double PI=acos(-1.0);
    inline ll read(){ll s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*w;}
    ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
    vector<int>G[maxn];
    int dfn[maxn],low[maxn],cut[maxn],i,u,v;
    int n,m,ans,tot;
    void tarjan(int u,int fa)
    {
        dfn[u]=low[u]=++tot;
        for(int i=0;i<G[u].size();i++)
        {
            int v=G[u][i];
            if(v==fa)continue;
            if(!dfn[v])
            {
                tarjan(v,u);
                low[u]=min(low[u],low[v]);
                if(low[v]>=dfn[u])cut[u]++;
            }
            low[u]=min(low[u],dfn[v]);
        }
    }
    int main()
    {
        n=read(),m=read();
        for (i=1;i<=m;i++)
        {
            u=read(),v=read();
            G[u].pb(v);
            G[v].pb(u);
        }
        for (i=1;i<=n;i++)
        {
            if (!dfn[i])
            {
                ans++;
                tarjan(i,-1);
                cut[i]--;
            }
        }
        for (i=1;i<=n;i++) cout<<cut[i]+ans<<" ";
        cout<<endl;
        return 0;
    }
    View Code

    I     Walking Machine

    水题

    J     Matrix Subtraction

    把原矩阵换成差分矩阵,那么与一个子矩阵相减,我们只需改变差分矩阵的四个点,时间效率大大提高,同时我们要考虑到底减多少。对于左上角的点,我们只能在这一次矩阵相减把这个点减至0,因为后续我们不可能回头再进行矩阵相减把左上角的点变成0,所以我们只需每次通过差分矩阵来反求出原矩阵的左上角的元素值,减去这个值把左上角元素变为0,再后面判断是否元素出现<0的情况即可。

    #include <bits/stdc++.h>
    #define debug freopen("r.txt","r",stdin)
    #define mp make_pair
    #define ri register int
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef double lf;
    typedef pair<ll, ll> pii;
    const int maxn = 1e3+10;
    const ll INF = 1e18;
    const int mod = 1e9+7;
    const double eps=1e-6;
    const double PI=acos(-1.0);
    inline ll read(){ll s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*w;}
    ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
    int n,m,a,b,t,i,j,flag;
    ll d[maxn][maxn],G[maxn][maxn];
    void add(int xa,int ya,int xb,int yb,ll val)
    {
        d[xa][ya]+=val;
        d[xb][yb]+=val;
        d[xa][yb]-=val;
        d[xb][ya]-=val;
    }
    int main()
    {
        t=read();
        while (t--)
        {
            n=read(),m=read(),a=read(),b=read();
            memset(d,0,sizeof(d));
            for (i=1;i<=n;i++)
                for (j=1;j<=m;j++) G[i][j]=read();
            for (i=1;i<=n;i++)
                for (j=1;j<=m;j++) d[i][j]=G[i][j]-G[i-1][j]-G[i][j-1]+G[i-1][j-1];
            flag=0;
            for (i=1;i<=n&&!flag;i++)
                for (j=1;j<=m&&!flag;j++)
                {
                    d[i][j]=d[i][j]+d[i-1][j]+d[i][j-1]-d[i-1][j-1];
                    if (d[i][j]<0) flag=1;
                    else if (d[i][j]>0)
                    {
                        if (i+a-1>n || j+b-1>m) flag=1;
                        else add(i,j,i+a,j+b,-d[i][j]);
                    }
                }
            if (flag) cout<<"QAQ"<<endl;
                else cout<<"^_^"<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    java解决跨域
    时间格式化
    base64图片实现文件上传
    java对Base64图片的加密解密
    A5/web项目连接Oracle 12c数据库报:ORA-01017: 用户名/口令无效
    JavaScript中call如何使用?
    C# 如何让new 出来的form显示在最外层?
    因为数据库和客户端字符集不一样原因,导致显示乱码???????,解决办法
    日语键盘按键修正记录
    keybd_event 在F按键系列不起作用的解决办法
  • 原文地址:https://www.cnblogs.com/Y-Knightqin/p/13898061.html
Copyright © 2011-2022 走看看