zoukankan      html  css  js  c++  java
  • codeforces-724

    题目链接: http://codeforces.com/contest/724/problem/B

    思路: 先把一步能够到达有序的情况枚举存在一个二维数组a里面。然后输入每一行 对每一行进行两两交换,交换后把对应的 a数组的状态加一。最后看是否存在到达n的状态。


    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<cmath>
    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<deque>
    #include<stack>
    #include<string>
    #include<vector>
    #include<iostream>
    #include<algorithm>
    #include<stdlib.h>
    #include<time.h>
    
    using namespace std;
    typedef long long LL;
    const int INF=2e9+1e8;
    const int MOD=1e9+7;
    const int MAXSIZE=1e6+5;
    const double eps=0.0000000001;
    void fre()
    {
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    }
    #define memst(a,b) memset(a,b,sizeof(a))
    #define fr(i,a,n) for(int i=a;i<n;i++)
    
    int n,m,dp[405][21],tot;
    int temp[22],ans[405];
    void init()
    {
        tot=0;
        memst(ans,0);
        for(int i=0; i<m; i++)
        {
            temp[i]=i+1;
            dp[tot][i]=i+1;
        }
        tot++;
        for(int i=0; i<m-1; i++)
            for(int j=i+1; j<m; j++)
            {
                for(int k=0; k<m; k++)
                {
                    if(k==i) dp[tot][j]=temp[k];
                    else if(k==j) dp[tot][i]=temp[k];
                    else dp[tot][k]=temp[k];
                }
                tot++;
            }
            return ;
    }
    bool cmp(int pos,int *a)
    {
        for(int i=0;i<m;i++) if(dp[pos][i]!=a[i]) return false;
        return true;
    }
    void bian(int *a)
    {
        for(int i=0;i<tot;i++)
        {
            if(cmp(i,a)) ans[i]++;
        }
    }
    void add()
    {
        int a[30];
        for(int i=0;i<m;i++) a[i]=temp[i];
        bian(a);
        for(int i=0; i<m-1; i++)
            for(int j=i+1; j<m; j++)
            {
                for(int k=0; k<m; k++)
                {
                    if(k==i) a[j]=temp[k];
                    else if(k==j) a[i]=temp[k];
                    else a[k]=temp[k];
                }
                bian(a);
            }
    }
    bool get()
    {
        for(int i=0;i<tot;i++) if(ans[i]==n) return true;
        return false;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        init();
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%d",&temp[j]);
            }
            add();
        }
        if(get()) printf("YES
    ");
        else printf("NO
    ");
        return 0;
    }
    
    // 复杂度  1e6  多一点

    另一个写法请参考 这个 。这个方法更容易理解。

    -----------------------------------------------------------------------分割线---------------------------------------------------------------------------------------------------------------------


     下面是 C 题 : http://codeforces.com/problemset/problem/722/C  

    有两篇文章,目前看了模拟这个想法,写了 模拟 的,做法二是 扩展欧几里得 + 计算几何

    模拟思路,预处理到边上的点的步数,对于一个点,往四个方向找,取最小值就可以了。

     

    #include <map>
    #include <set>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <sstream>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    const int MAX=100005;
    typedef long long int LL;
    
    int a[MAX],b[MAX];
    LL vis[MAX][4][4];
    int n,m,k;
    void init()
    {
        memset(vis,-1,sizeof(vis));
        int tmp=0;
        int x=0,y=0;
        LL ti=0;
        while(1)
        {
            if(tmp==0)
            {
                if((n-x)+y==m) break;
                if((n-x)+y<m)
                    vis[(n-x)+y][3][0]=ti+n-x,ti=ti+n-x,y=(n-x)+y,x=n,tmp=3;
                else
                    vis[x+(m-y)][2][0]=ti+m-y,ti=ti+m-y,x=x+(m-y),y=m,tmp=1;
            }
            else if(tmp==1)
            {
                if(y-(n-x)==0) break;
                if(y>n-x)
                    vis[y-(n-x)][3][1]=ti+(n-x),ti=ti+(n-x),y=y-(n-x),x=n,tmp=2;
                else
                    vis[x+y][0][1]=ti+y,ti=ti+y,x=x+y,y=0,tmp=0;
            }
            else if(tmp==2)
            {
                if(x==y) break;
                if(x<y)
                    vis[y-x][1][2]=ti+x,ti=ti+x,y=y-x,x=0,tmp=1;
                else
                    vis[x-y][0][2]=ti+y,ti=ti+y,x=x-y,y=0,tmp=3;
            }
            else if(tmp==3)
            {
                if(y+x==m) break;
                if(y+x<m)
                    vis[y+x][1][3]=ti+x,ti=ti+x,y=y+x,x=0,tmp=0;
                else
                    vis[x-(m-y)][2][3]=ti+(m-y),ti=ti+(m-y),x=x-(m-y),y=m,tmp=2;
            }
        }
        return ;
    }
    int main()
    {
        while(cin>>n>>m>>k)
        {
            for(int i=0; i<k; i++)
            {
                scanf("%d%d",&a[i],&b[i]);
            }
            init();
            for(int i=0; i<k; i++)
            {
                LL ans=1e18;
                if(a[i]==b[i])
                {
                    printf("%d
    ",a[i]);
                    continue;
                }
    
                if((n-a[i])+b[i]>m)
                {
                    if(vis[a[i]+(m-b[i])][2][3]!=-1)
                    {
                        ans=min(ans,vis[a[i]+(m-b[i])][2][3]+m-b[i]);
                    }
                }
                if((n-a[i])+b[i]<m)
                {
                    if(vis[b[i]+n-a[i]][3][1]!=-1)
                    {
                        ans=min(ans,vis[b[i]+n-a[i]][3][1]+n-a[i]);
                    }
                }
    
                if(b[i]>n-a[i])
                {
                    if(vis[b[i]-(n-a[i])][3][0]!=-1)
                    {
                        ans=min(ans,vis[b[i]-(n-a[i])][3][0]+n-a[i]);
                    }
                }
                if(b[i]<n-a[i])
                {
                    if(vis[a[i]+b[i]][0][2]!=-1)
                    {
                        ans=min(ans,vis[a[i]+b[i]][0][2]+b[i]);
                    }
                }
    
                if(a[i]<b[i])
                {
                    if(vis[b[i]-a[i]][1][3]!=-1)
                    {
                        ans=min(ans,vis[b[i]-a[i]][1][3]+a[i]);
                    }
                }
                if(a[i]>b[i])
                {
                    if(vis[a[i]-b[i]][0][1]!=-1)
                    {
                        ans=min(ans,vis[a[i]-b[i]][0][1]+b[i]);
                    }
                }
    
                if(a[i]+b[i]>m)
                {
                    if(vis[a[i]-(m-b[i])][2][0]!=-1)
                    {
                        ans=min(ans,vis[a[i]-(m-b[i])][2][0]+(m-b[i]));
                    }
                }
                if(a[i]+b[i]<m)
                {
                    if(vis[a[i]+b[i]][1][2]!=-1)
                    {
                        ans=min(ans,vis[a[i]+b[i]][1][2]+a[i]);
                    }
                }
                if(ans!=1e18) printf("%I64d
    ",ans);
                else printf("-1
    ");
            }
        }
        return 0;
    }
    



  • 相关阅读:
    C语言程序设计第四次作业
    C语言程序设计第三次作业
    C语言程序设计第二次作业
    python网络编程 day34 网络编程——线程的相关概念及开启线程
    python网络编程 day33 网络编程——进程拾遗,互斥锁(重要)生产者消费者模型
    python网络编程 day32 网络编程——进程multiprocessing模块及join用法
    文件上传下载代码
    python网络编程 day30 网络编程——hmac模块与hashlip、socketserver、粘包问题
    python网络编程 day29 网络编程初识 ——tcp与udp、struck模块
    python网络编程 day28 网络编程初识 ——socket
  • 原文地址:https://www.cnblogs.com/coded-ream/p/7207946.html
Copyright © 2011-2022 走看看