zoukankan      html  css  js  c++  java
  • 【SDOI2009】解题汇总

    又开了波专题,感觉就和炉石开冒险一样...(说的好像我有金币开冒险似的)
    

    /—————————————————————————————————————————————/
    BZOJ-1226 【SDOI2009】学校食堂Dining
    状态压缩DP

    f【i】【j】【k】表示前i-1人都吃过饭,j表示i与i之后7人的吃饭情况,k表示上一个吃饭的人与i的相对位置 转移如程序;
    这题需要注意一些小细节: 后面同学的领饭情况需要压8位而不是7位 当一个同学已经领到饭的时候,他的忍耐度就可以忽略了
    code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    using namespace std;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-')f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define maxn 1010
    int tim,n,ans;
    struct data{int t,b;}st[maxn];
    int f[maxn][1<<9][20];
    
    int work(int x,int y)
    {
        if (x==0) return 0;
        return st[x].t^st[y].t; 
    }
    
    #define inf 0x7fffffff
    void DP()
    {
        //memset(f,127,sizeof(f));
        for(int i=1;i<=n+1;i++)
            for(int j=0; j<(1<<8);j++)
                for(int k=-8; k<=7; k++)
                    f[i][j][k+8]=inf;
        f[1][0][7]=0;
        for (int i=1; i<=n; i++)
            for (int j=0; j<(1<<8); j++)
                for (int k=-8; k<=7; k++)
                    {
                        if (f[i][j][k+8]<inf)
                            if (j&1) f[i+1][j>>1][k+7]=min(f[i][j][k+8],f[i+1][j>>1][k+7]);
                        else
                            {
                                int r=inf;
                                for(int l=0; l<8; l++)
                                {
                                    if(!(j&(1<<l)))
                                    {
                                        if(i+l>r) break;
                                        r=min(r,i+l+st[i+l].b);
                                        f[i][j+(1<<l)][l+8]=min(f[i][j+(1<<l)][l+8],f[i][j][k+8]+work(i+k,i+l));
                                    }
                                }
                            }   
                    }
    }
    
    int main()
    {
        tim=read();
        while (tim--)
            {
                n=read();
                for (int i=1; i<=n; i++) st[i].t=read(),st[i].b=read();
                /*puts("OK");*/ DP(); /*puts("OK");*/  ans=inf;
                for (int i=-8; i<0; i++) ans=min(f[n+1][0][i+8],ans);
                printf("%d
    ",ans);
            }
        return 0;
    } 

    異次元の传送阵http://blog.csdn.net/dad3zz/article/details/50930294
    /—————————————————————————————————————————————/
    BZOJ-1227【SDOI2009】虔诚的墓主人
    树状数组+离散化+组合数学

    如果a,b在同一行,则ans+=c(l[a]+1(包括a),k)*c(r[b]+1,k)再分别乘上ab间的每一个点的c(u[i],k)*c(d[i],k)
    l[a],r[a],u[a],d[a]表示一个点上下左右的点数,可以预处理,也可以边做边记录
    需要优化时间复杂度,于是要用树状数组维护a到b所有点的c(u[i],k)*c(d[i],k)之和
    从左往右处理某行的某一个点时,要将树状数组中该点横坐标位置上的数进行修改
    修改的值为就是现在的c(u[i],k)*c[d[i],k]减去原来的,也就是c(u[i],k)*c[d[i],k]-c(u[i]+1,k)*c[d[i]-1,k]

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define maxw 100010
    #define p 2147483648LL
    int n,m,w,k,l;
    struct data
    {
        int x,y;
        bool operator < (const data & A) const
            {
                if (y==A.y) return x<A.x;
                return y<A.y;
            }
    }tr[maxw];
    long long tree[maxw*2],C[maxw*2][15],ans;
    int ls[maxw*2],cnt,num,now[maxw*2];
    int xx[maxw*2],yy[maxw*2];
    
    int lowbit(int x)
    {
        return x&(-x);
    }
    void add(int x,int dat)
    {
        for (int i=x; i<=w*2; i+=lowbit(i)) tree[i]=(tree[i]+dat)%p;
    }
    long long query(int x)
    {
        long long re=0;
        for (int i=x; i>0; i-=lowbit(i)) re=(re+tree[i])%p;
        return re;
    }
    
    int getloc(int dat)
    {
        int l=1,r=cnt;
        while (l<=r)
            {
                int mid=(l+r)>>1;
                if (ls[mid]<dat) l=mid+1;
                else if (ls[mid]>dat) r=mid-1;
                else return mid;            
            }
    }
    
    void getC()
    {
        C[0][0]=1;
        for (int i=1; i<=w; i++)
            {
                C[i][0]=1;
                for (int j=1; j<=min(k,i); j++)
                    C[i][j]=(C[i-1][j]+C[i-1][j-1])%p;
            }
    }
    
    int main()
    {
        n=read(),m=read();
        w=read();
        for (int i=1; i<=w; i++) ls[++cnt]=tr[i].x=read(),ls[++cnt]=tr[i].y=read();
        k=read();
        sort(ls+1,ls+cnt+1);
        //for (int i=2; i<=cnt; i++) if (ls[i]!=ls[i-1]) ls[++num]=ls[i];
        //for (int i=1; i<=w; i++) tr[i].x=getloc(tr[i].x),tr[i].y=getloc(tr[i].y);
        for (int i=1; i<=w; i++) xx[getloc(tr[i].x)]++,yy[getloc(tr[i].y)]++;
        getC(); sort(tr+1,tr+w+1);
        //for (int i=1; i<=w; i++)
            //printf("%d %d
    ",getloc(tr[i].x),getloc(tr[i].y));
        for(int i=1;i<=w;i++)
            {
                if(i>1 && tr[i].y==tr[i-1].y)
                    l++,ans+=(query(getloc(tr[i].x)-1)-query(getloc(tr[i-1].x)))*(C[l][k]*C[yy[getloc(tr[i].y)]-l][k]),ans%=p;
                else l=0;
                int loc=getloc(tr[i].x); now[loc]++;
                int delta=(C[now[loc]][k]*C[xx[loc]-now[loc]][k]-C[now[loc]-1][k]*C[xx[loc]-now[loc]+1][k])%p;
                add(loc,delta);
            }
        if (ans<0) ans+=p; 
        printf("%lld
    ",ans);
        return 0;
    } 

    異次元の传送阵http://blog.csdn.net/dad3zz/article/details/50930241
    /—————————————————————————————————————————————/
    BZOJ-1228【SDOI2009】E&D
    SG函数+打表找规律

    RT….后来发现好像是个叫 ‘’ 阿达马矩阵 ‘’的东西
    找规律,然后异或下答案….

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    int t,n,ans;
    int sg(int x, int y) 
    {
        int tmp=1<<30,re=31;
        for (int i=30; i; i--)
            {
                if (x<=tmp && y<=tmp) re=i;
                    else 
                        {
                            if (x>tmp) x-=tmp;
                            if (y>tmp) y-=tmp;
                        }
                tmp>>=1;
            }
        if (x==1 && y==1) return 0;
        return re;
    }
    int main()
    {
        t=read();
        while (t--)
            {
                n=read(),ans=0;
                int x,y;
                for (int i=1; i<=n/2; i++) 
                    x=read(),y=read(),ans^=sg(x,y);
                if (ans) puts("YES");
                    else puts("NO");                
            }
        return 0;
    }

    異次元の传送阵http://blog.csdn.net/dad3zz/article/details/50906980
    /—————————————————————————————————————————————/
    BZOJ-1235【SDOI2009】细胞探索
    FloodFill + 大暴力
    code:实在是不愿意打搜索QAQ….
    異次元の传送阵移至GTY大哥的BLOG吧! http://gaotianyu1350.gitcafe.io/2015/04/07/BZOJ1235-细胞探索/
    /—————————————————————————————————————————————/
    BZOJ-1875【SDOI2009】HH去散步
    DP+矩乘快速幂优化

    正常是对点构造矩阵,那么这里用边来构造,保证走的时候不经过反向边即可,然后矩乘快速幂加速
    code:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define maxn 25
    #define maxm 70
    #define p 45989
    int n,m,t,st,ed;
    struct data{int to,next;}edge[maxm*2];
    int head[maxm],cnt;
    int l,ans;
    struct Mat{int a[maxm*2][maxm*2];Mat(){memset(a,0,sizeof(a));}};
    
    void add(int u,int v)
    {
        cnt++;
        edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt;
    }
    
    Mat mul(Mat A,Mat B)
    {
        Mat re;
        for (int i=1; i<=l; i++)
            for (int j=1; j<=l; j++)
                for (int k=1; k<=l; k++)
                    re.a[i][j]=(re.a[i][j]+(A.a[i][k]*B.a[k][j])%p)%p;
        return re;              
    }
    
    Mat quick_mul(Mat A,int x)
    {
        Mat re;
        for (int i=1; i<=l; i++) re.a[i][i]=1;
        while (x)
            {
                if (x&1) re=mul(re,A);
                x>>=1; A=mul(A,A);
            }
        return re;
    }
    
    int findre(int x)
    {
        if (x&1) return x+1;
            else return x-1;
    }
    
    int main()
    {
        n=read(),m=read(),t=read(),st=read(),ed=read();
        for (int i=1; i<=m; i++)
            {
                int u=read(),v=read();
                add(u,v); add(v,u);
            }
        Mat x,y;
        for (int i=head[st]; i; i=edge[i].next)
            x.a[1][i]=1;
        l=cnt;  
        if (t==0) {if (st==ed) puts("1"); else puts("0"); return 0;}
        for (int i=1; i<=l; i++)
            for (int j=head[edge[i].to]; j; j=edge[j].next)
                if (j!=findre(i)) y.a[i][j]=1;
        x=mul(x,quick_mul(y,t-1));                          
        for (int i=head[ed]; i; i=edge[i].next)
            ans=(ans+x.a[1][findre(i)])%p;
        printf("%d
    ",ans);     
        return 0;
    }

    異次元の传送阵http://blog.csdn.net/dad3zz/article/details/50930113
    /—————————————————————————————————————————————/
    BZOJ-1876【SDOI2009】SuperGCD
    高精度取模 变态题 +Python

    抱歉Python几行干掉

    code:

    a=(int)(input())
    b=(int)(input())
    while b!=0:
        t=a
        a=b
        b=t%b
    print(a)

    異次元の传送阵http://blog.csdn.net/dad3zz/article/details/50930144
    /—————————————————————————————————————————————/
    BZOJ-1877【SDOI2009】晨跑
    拆点+傻逼费用流

    建图: 把除了编号1和n的点拆点,正常连边,若两点相连,用一个点的出点连另一个点的入点;
    一个点拆成的入点和出点间连容量为1,费用为0;
    源点为1,汇点为n;
    最后最大流为最多天数,最小费用为最短路径

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define maxn 205
    #define maxm 20010
    int n,m;
    struct data{int to,next,cap,cost;}edge[maxn*2+maxm*2];
    int head[maxn*2],cnt=1;
    int S,T;
    int len[maxn][maxn];
    
    void add(int u,int v,int w,int c)
    {
        cnt++;
        edge[cnt].to=v; edge[cnt].cost=c; edge[cnt].cap=w;
        edge[cnt].next=head[u]; head[u]=cnt;
    }
    void insert(int u,int v,int w,int c)
    {
        add(u,v,w,c); add(v,u,0,-c);
    }
    
    #define inf 0x7fffffff
    bool visit[maxn*2];
    int dis[maxn*2];
    bool mark[maxn*2];
    int q[maxm*10],h,t;
    int anst,ansl;
    bool spfa()
    {
        memset(visit,0,sizeof(visit));
        for (int i=0; i<=(n-2)*2+2; i++) dis[i]=inf;
        h=0,t=1;
        q[0]=T;dis[T]=0;visit[T]=1;
        while (h<t)
            {
                int now=q[h];h++;
                for (int i=head[now]; i; i=edge[i].next)
                    if (edge[i^1].cap && dis[now]-edge[i].cost<dis[edge[i].to])
                        {
                            dis[edge[i].to]=dis[now]-edge[i].cost;
                            if (!visit[edge[i].to])
                                {
                                    q[t++]=edge[i].to;
                                    visit[edge[i].to]=1;
                                }
                        }
                visit[now]=0;
            }
        return dis[S]!=inf;
    }
    
    int dfs(int loc,int low)
    {
        mark[loc]=1;
        if (loc==T) return low;
        int w,used=0;
        for (int i=head[loc]; i; i=edge[i].next)
            if (edge[i].cap && !mark[edge[i].to] && dis[edge[i].to]==dis[loc]-edge[i].cost)
                {
                    w=dfs(edge[i].to,min(low-used,edge[i].cap));
                    ansl+=w*edge[i].cost;
                    used+=w;
                    edge[i].cap-=w;edge[i^1].cap+=w;
                    if (used==low) return low;
                }
        return used;
    }
    
    void zkw()
    {
        int tmp=0;
        while (spfa())
            {
                mark[T]=1;
                while (mark[T])
                    {
                        memset(mark,0,sizeof(mark));
                        tmp+=dfs(S,inf);
                    }
            }
        anst=tmp;
    }
    
    //一眼拆点,给定的长度为费用,每条边的容量为1 
    void make()
    {
        S=1; T=n;
        for (int i=2; i<=n-1; i++)
            insert(i,i+n-1,1,0);
        for (int i=2; i<=n-1; i++)
            for (int j=1; j<=n; j++)
                if (len[i][j]!=0)
                    insert(i+n-1,j,1,len[i][j]);
        for (int i=1; i<=n; i++)
            if (len[1][i]!=0) insert(1,i,1,len[1][i]);
    }
    
    int main()
    {
        n=read(),m=read();
        int from,to;
        for (int i=1; i<=m; i++)
            from=read(),to=read(),len[from][to]=read();
        make();
        zkw();
        printf("%d %d
    ",anst,ansl);
        return 0;
    }

    異次元の传送阵http://blog.csdn.net/dad3zz/article/details/50907874
    /—————————————————————————————————————————————/
    BZOJ-1878【SDOI2009】HH的项链
    树状数组+莫队算法

    在线操作的话,无法判重,所以考虑离线。 对询问的左端排序,然后从小到大做;严格意义上不是莫队,但是是应用了莫队的思想。
    然后在读入颜色时,进行些处理,处理出每个颜色下一次出现的位置。 在处理询问时,加入下一个颜色,答案即为前缀和相减。

    code:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define maxn 50010
    #define maxm 200010
    #define maxcol 1000010
    int n,m,maxcolor;
    int color[maxn];
    struct data
    {
        int l,r,id;
        bool operator < (const data & A) const
            {
                return l<A.l;
            }
    }ask[maxm];
    int ans[maxm];
    int next[maxn],pre[maxcol];
    int tree[maxn];
    int lowbit(int x)
    {
        return x&(-x);
    }
    void add(int x,int dat)
    {
        for (int i=x; i<=n; i+=lowbit(i))
            tree[i]+=dat;
    }
    int query(int x)
    {
        int re=0;
        for (int i=x; i>0; i-=lowbit(i))
            re+=tree[i];
        return re;
    }
    int main()
    {
        n=read();
        for (int i=1; i<=n; i++) 
            color[i]=read(),maxcolor=max(maxcolor,color[i]);
        for (int i=n; i>0; i--)
            next[i]=pre[color[i]],pre[color[i]]=i;
        for (int i=1; i<=maxcolor; i++)
            if (pre[i]) add(pre[i],1);
        m=read();
        for (int i=1; i<=m; i++) 
            ask[i].l=read(),ask[i].r=read(),ask[i].id=i;
        sort(ask+1,ask+m+1);
        int loc=1;
        for (int i=1; i<=m; i++)
            {
                while (loc<ask[i].l)
                    {
                        if (next[loc]) add(next[loc],1);
                        loc++;
                    }
                ans[ask[i].id]=query(ask[i].r)-query(ask[i].l-1);
                //printf("%d %d %d %d
    ",ask[i].l,ask[i].r,query(ask[i].r),query(ask[i].l-1));
            }
        for (int i=1; i<=m; i++) printf("%d
    ",ans[i]);
        return 0;
    }

    異次元の传送阵http://blog.csdn.net/dad3zz/article/details/50908757
    /—————————————————————————————————————————————/
    BZOJ-1879【SDOI2009】Bill的挑战
    状态压缩DP

    思路比较简单:
    f【i】【j】表示 匹配到第i位,时状态为j的方案数;
    具体的转移:
    f[i+1][j&(g[i][l])]+=f[i][j],f[i+1][j&(g[i][l])]%=p;
    用g来存储状态,枚举状态即可;

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define p 1000003
    int t,n,k;
    char s[20][60];
    
    int f[60][1<<15],g[60][1<<5];
    void DP()
    {
        memset(f,0,sizeof(f)); memset(g,0,sizeof(g));
        int len=strlen(s[1]);
        for (int i=0; i<len; i++)
            for (int j=1; j<=n; j++)
                for (int l=0; l<26; l++)
                    if (s[j][i]=='?' || s[j][i]=='a'+l)
                        g[i][l]|=1<<(j-1);
        f[0][(1<<n)-1]=1;
        for (int i=0; i<len; i++)
            for (int j=0; j<(1<<n); j++)
                if (f[i][j]!=0)
                    for (int l=0; l<26; l++)
                        f[i+1][j&(g[i][l])]+=f[i][j],f[i+1][j&(g[i][l])]%=p;
        int ans=0;
        for (int i=0; i<(1<<n); i++)
            {
                int now=i,tmp=0;
                while (now) tmp+=now&1,now>>=1;
                if (tmp==k) ans=(ans+f[len][i])%p;
            }
        printf("%d
    ",ans);
    }
    
    int main()
    {
        t=read();
        while (t--)
            {
                n=read(),k=read();
                for (int i=1; i<=n; i++)
                    scanf("%s",s[i]);
                DP();
            }
        return 0;
    } 

    異次元の传送阵http://blog.csdn.net/dad3zz/article/details/50937084
    /—————————————————————————————————————————————/
    BZOJ-1880【SDOI2009】Elaxia的路线
    SPFA+枚举

    4遍spfa,开四个dis数组,分别记录st1,st2,ed1,ed2到各点的最短路,然后枚举点对(i,j)判断i,j是否在最短路径上,然后更新答案即可.

    code:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    using namespace std;
    int read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    #define maxn 1510
    #define maxm 500010
    int n,m,ans;
    int st1,st2,ed1,ed2;
    int len1,len2;
    struct data{int to,next,tim;}edge[maxm*2];
    int head[maxn],cnt;
    
    void add(int u,int v,int t)
    {
        cnt++;
        edge[cnt].next=head[u]; head[u]=cnt;
        edge[cnt].to=v; edge[cnt].tim=t;
    }
    void insert(int u,int v,int t)
    {
        add(u,v,t); add(v,u,t);
    }
    
    int disst1[maxn],disst2[maxn],dised1[maxn],dised2[maxn];
    bool visit[maxn];
    #define inf 0x7fffffff
    void spfa(int s,int* dis)
    {
        queue<int>q;
        for (int i=1; i<=n; i++) dis[i]=inf;
        q.push(s); dis[s]=0;
        while (!q.empty())
            {
                int now=q.front(); q.pop();
                for (int i=head[now]; i; i=edge[i].next)
                    if (dis[now]+edge[i].tim<dis[edge[i].to])
                        {
                            dis[edge[i].to]=edge[i].tim+dis[now];
                            if (!visit[edge[i].to])
                                {
                                    q.push(edge[i].to);
                                    visit[edge[i].to]=1;
                                }
                        }
                visit[now]=0;
            }
    }
    
    bool check(int loc)
    {
        if (disst1[loc]+dised1[loc]!=len1 || disst2[loc]+dised2[loc]!=len2) 
            return false;
        return true;
    }
    
    int main()
    {
        n=read(),m=read();
        st1=read(),ed1=read(),st2=read(),ed2=read();
        for (int i=1; i<=m; i++)
            {
                int u=read(),v=read(),t=read();
                insert(u,v,t);
            }
        spfa(st1,disst1); spfa(st2,disst2);
        spfa(ed1,dised1); spfa(ed2,dised2);
        len1=disst1[ed1]; len2=disst2[ed2];
        for (int i=1; i<=n; i++)
            if (check(i))
                for (int j=1; j<=n; j++)
                    if (check(j))
                        ans=max(ans,abs(disst1[i]-disst1[j]));
        printf("%d
    ",ans);
        return 0;
    }

    異次元の传送阵http://blog.csdn.net/dad3zz/article/details/50930197
    /—————————————————————————————————————————————/

    总结:
    SDOI2009没什么大数据结构题,但是DP相当多吗,状压DP更是出现两道….当务之急是抓好DP,类似的思想要记住。 对于状压DP,在写转移之前,先思考需要如何转移,再思考状压的状态即可,一般用and,or等进行变换,不能慌。
    对于一些数论题,或者博弈题,找规律不能空想,先暴力打标,对表找规律。
    数据值极大,但数据量不大,且需要用值时,首先考虑离散即可,很多时候,不要求强制在线,可以优先考虑下离线的做法,可能效果拔群
    网络流建模不要慌,对于限制次数,只需要拆点。(这不是早就知道的吗…)

    成果图:
    这里写图片描述

  • 相关阅读:
    Java 数据类型转换
    Perl 日期时间函数(date time)
    find a filename from a filehandle in Perl
    Perl文件读写
    R语言算术运算和逻辑运算
    bash/shell 数学计算
    grep/awk/sed 或者 并且 否定
    关于打印 毕业设计资料
    python 捕获 shell/bash 脚本的输出结果
    推荐几个高质量的图片素材网站
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5346152.html
Copyright © 2011-2022 走看看