• Topcoder SRM 628 DIV 2


    被自己蠢哭了。。。。

    250-point problem

    国际象棋棋盘上给出两个坐标,问象从一个走到还有一个最少要几步。

    黑格象仅仅能走黑格,白格象仅仅能走白格,仅仅要推断两个坐标的颜色是否同样就能推断是否可达,观察棋盘能够发现坐标的奇偶性决定了格子的颜色;可达的情况下最多两步就能达到,所以仅仅要推断格子是否在同一条斜线上即可了。

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    #include<ctime>
    #include<cctype>
    #include<cmath>
    #include<string>
    #include<cstring>
    #include<stack>
    #include<queue>
    #include<list>
    #include<vector>
    #include<map>
    #include<set>
    #define sqr(x) ((x)*(x))
    #define LL long long
    #define itn int
    #define INF 0x3f3f3f3f
    #define PI 3.1415926535897932384626
    #define eps 1e-10
    #define maxm
    #define maxn
    
    using namespace std;
    
    class BishopMove
    {
    public:
        int howManyMoves(int r1, int c1, int r2, int c2)
        {
            if (r1==r2 && c1==c2)   return 0;
            if (((r1+c1)&1) == ((r2+c2)&1))
            {
                if (abs(r1-r2)==abs(c1-c2)) return 1;
    
                return 2;
            }
    
    
            return -1;
        }
    };
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("/home/fcbruce/文档/code/t","r",stdin);
        #endif // ONLINE_JUDGE
    
    
    
        return 0;
    }
    


    500-point problem

    给出一个括号序列,X可被括号替换,问这串序列是否可能合法。由于当时没看见X的数量不超过5就用了区间DP,有一处下标竟然没控制好结果RE。。。。事实上能够用DFS求出全部可能的序列,然后用栈推断;区间DP仅仅要求出对这段序列最少加多少括号使其合法即可,假设为0就是合法的,要注意对匹配括号的推断。

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    #include<ctime>
    #include<cctype>
    #include<cmath>
    #include<string>
    #include<cstring>
    #include<stack>
    #include<queue>
    #include<list>
    #include<vector>
    #include<map>
    #include<set>
    #define sqr(x) ((x)*(x))
    #define LL long long
    #define itn int
    #define INF 0x3f3f3f3f
    #define PI 3.1415926535897932384626
    #define eps 1e-10
    #define maxm
    #define maxn
    
    using namespace std;
    
    class BracketExpressions
    {
    public:
        bool check(char x,char y)
        {
            if (x=='(' && y==')' || x=='['&& y==']' ||x=='{' && y=='}')
                return true;
    
            if (x=='X' && (y==']' || y=='}' || y==')' || y=='X')) return true;
    
            if (y=='X' && (x=='(' || x=='[' || x=='{')) return true;
    
            return false;
        }
        string ifPossible(string str)
        {
            int l=str.size();
    
            int dp[60][60];
            memset(dp,0,sizeof dp);
            for(int i = 0; i<l; i++)
            {
                dp[i][i] = 1;
            }
    
            for (int m=1;m<l;m++)
            {
                for (int i=0;i<l;i++)
                {
                    int j=i+m;
                    if (j>=l)   break;
                    dp[i][j]=INF;
                    if (check(str[i],str[j]))
                        dp[i][j]=min(dp[i][j],dp[i+1][j-1]);
                    for (int k=i;k<j;k++)
                    {
                        dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
                    }
                }
            }
    
            if (dp[0][l-1]==0)  return "possible";
            else
                return "impossible";
        }
    };
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("/home/fcbruce/文档/code/t","r",stdin);
        #endif // ONLINE_JUDGE
    
    
    
        return 0;
    }
    


    1000-point problem

    时间不够,比赛的时候没来得及敲完。。。。。

    题意:

    给出一个有n个元素的集合E={ x | 0<=x<n , x为整数 },和一段序列f={ xi | 0<=xi,i<n },对于集合E的子集S,有随意i属于S,f[i]=xi 也属于S,问这种子集有多少个。

    分析:

    这事实上是个图论。

    对于每一个i,都相应一个f[i]=xi,假设我取i,那我必然也要取f[i]=xi,即i依赖于f[i]=xi。于是建立有向边i---->f[i]=xi;对于图中的每一个强联通分量,这个分量中的全部点一定是同一时候取的。我们能够进行强联通缩点(tarjan),剩下的DAG中每一个点都有取和不取两种关系。应用乘法原理和加法原理,反向建图后通过树形DP求得最后的方案数:对于节点u,取这个节点的方案数是它全部子节点的方案数相乘,不取这个节点的方案数为1。

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    #include<ctime>
    #include<cctype>
    #include<cmath>
    #include<string>
    #include<cstring>
    #include<stack>
    #include<queue>
    #include<list>
    #include<vector>
    #include<map>
    #include<set>
    #define sqr(x) ((x)*(x))
    #define LL long long
    #define itn int
    #define INF 0x3f3f3f3f
    #define PI 3.1415926535897932384626
    #define eps 1e-10
    #define maxm 555555
    #define maxn 55
    
    using namespace std;
    
    int fir[maxn];
    int u[maxm],v[maxm],nex[maxm];
    long long w[maxn];
    int n;
    
    int pre[maxn],low[maxn],sccno[maxn];
    int st[maxn],top;
    int dfs_clock,scc_cnt;
    
    int deg[maxn];
    
    void tarjan_dfs(int _u)
    {
        pre[_u]=low[_u]=++dfs_clock;
        st[++top]=_u;
        for (int e=fir[_u];e!=-1;e=nex[e])
        {
            int _v=v[e];
            if (pre[_v]==0)
            {
                tarjan_dfs(_v);
                low[_u]=min(low[_u],low[_v]);
            }
            else
            {
                if (sccno[_v]==0)
                    low[_u]=min(low[_u],pre[_v]);
            }
        }
    
        if (low[_u]==pre[_u])
        {
            scc_cnt++;
            while (true)
            {
                int x=st[top--];
                sccno[x]=scc_cnt;
                if (x==_u)   break;
            }
        }
    }
    
    void find_scc()
    {
        dfs_clock=scc_cnt=0;
        top=-1;
        memset(sccno,0,sizeof sccno);
        memset(pre,0,sizeof pre);
        for (int i=0;i<n;i++)
        {
            if (pre[i]==0)  tarjan_dfs(i);
        }
    }
    
    long long dfs(int _u)
    {
        long long temp=1;
        for (int e=fir[_u];~e;e=nex[e])
        {
            temp*=dfs(v[e]);
        }
    
        return temp+1;
    }
    
    class InvariantSets
    {
    public:
        long long countSets(vector <int> f)
        {
            n=f.size();
    
            memset(fir,-1,sizeof fir);
    
            for (int i=0;i<n;i++)
            {
                u[i]=i;v[i]=f[i];
                nex[i]=fir[i];fir[i]=i;
            }
    
            find_scc();
    
            memset(fir,-1,sizeof fir);
            memset(deg,0,sizeof deg);
    
            int e=0;
    
            for (int i=0;i<n;i++)
            {
                if (sccno[u[i]]==sccno[v[i]])   continue;
    
                u[e]=sccno[u[i]];v[e]=sccno[v[i]];
    
                swap(u[e],v[e]);
    
                nex[e]=fir[u[e]];
                deg[v[e]]++;
                fir[u[e]]=e++;
            }
    
            for (int i=1;i<=scc_cnt;i++)
            {
                if (deg[i]==0)
                {
                    u[e]=i;v[e]=0;
                    swap(u[e],v[e]);
                    nex[e]=fir[u[e]];
                    fir[u[e]]=e++;
                }
            }
    
            return dfs(0)-1;
    
    
    
        }
    };
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("/home/fcbruce/文档/code/t","r",stdin);
        #endif // ONLINE_JUDGE
    
        InvariantSets a;
        itn x,y;
        while (~scanf("%d",&x))
        {
            vector <int>    v;
            for (int i=0;i<x;i++)
            {
                scanf("%d",&y);
                v.push_back(y);
            }
    
            printf("%lld
    ",a.countSets(v));
        }
    
    
        return 0;
    }
    


  • 相关阅读:
    二叉树
    tomcat和jvm调优
    服务器正向代理
    LRU算法
    《转载》TCP三次握手中SYN,ACK,Seq三者的关系
    python的字符串、集合、for循环、异常等基础语法
    configparser_配置解析器
    hashlib模块
    悟_面向对象_小游戏和进阶
    面向对象_new,__eq__,__hash__
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4265632.html
Copyright © 2020-2023  润新知