zoukankan      html  css  js  c++  java
  • 伪Acmer的推理(dfs/bfs)

    时间限制:1000MS  内存限制:65535K
    提交次数:12 通过次数:9 收入:32

    题型: 编程题   语言: C++;C

    Description

    现在正是期末,在复习离散数学的Acmer遇到了问题,你能帮助他吗?
    Acmer正在复习的是推理,不过他的推理系统可能与别人的不一样。
    (所以说他是一个伪Acmer~。做完这题,请自觉把这里伪Acmer自己定义的概念忘了。。否则到时学离散的时候混淆了概念的话自重。。。)
    他的推理系统定义如下:
    1.用大写英文字母A-Z表示一个命题。
    2.用A→B表示若命题A成立则命题B成立。
    3.用A↔B表示A→B且B→A。
    (这里2,3皆表示一种逻辑关系。)
    推理就是由若干个命题或逻辑关系出发,推出新的命题或逻辑关系。
    如,已知A→B和B→C,我们可以推出A→C。
    又如,已知A→B和A,我们可以推出B。
    再如,如果仅有A、B成立,是不可以推出A→B的。
    。。。。。。
    现在Acmer已经知道了n个命题或逻辑关系是成立的。而且,他从这些前提出发,又推出了m个新的命题或逻辑关系出来。
    不过,他的推理过程并不一定正确。所以,你能告诉他这m个结论中哪些是正确的,哪些是错误的吗?




    输入格式

    单case输入。
    第一行是一个整数n(0<=n<=100)。
    接下来n行,每行表示1个已知成立的命题或逻辑关系。
    每行首先是一个数字x(1<=x<=3),
      若是1,后面接一个大写英文字母,表示一个命题。
      若是2,后面接两个大写英文字母,表示逻辑关系→。
      若是3,后面接两个大写英文字母,表示逻辑关系↔。
    接着是一个整数m(0 < m <= 100)。
    接下来m行,每行表示1个要求判断正误的命题或逻辑关系。
    每行的格式同上。



    输出格式

    输出m行。对每个要你判断的结论,正确的话输出“yes”,否则输出“no”。



    输入样例

    Sample#1:
    2
    2	A 	B
    2	B	C
    1
    2	A	C
    
    Sample#2:
    1
    2	A	B
    1
    1	B
    
    Sample#3:
    2
    2	A	B
    1	A
    1
    1	B



    输出样例

    Sample#1:
    yes
    
    Sample#2:
    no
    
    Sample#3:
    yes



    提示

    Sample#不是输入输出的一部分。
    注意区别命题和逻辑关系成立的不同。

    思路:直接dfs暴力搜一遍,被坑了一下(花了1积分)囧 例子:
    0
    1
    3    Z    Z
    答案应该是 yes
    /*time  memy
      31ms  3854k
      by orc
      2015 4 16
      */
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <vector>
    using namespace std;
    int vis[30], vis2[30];
    int n, x;
    int t;
    char u, v, k;
    vector<int> G[30];
    void read_graph()
    {
        cin >> n;
        memset(vis,0,sizeof vis );
        for(int i = 0; i < n; ++i)
        {
            cin >> t;
            if(t == 1) { cin >> k; vis[k - 'A'] = 1; continue; }//单个点直接标记为成立
            else if(t == 2) {  cin >> u >> v; G[u-'A'].push_back(v - 'A'); }
            else {  cin >> u >> v; G[u-'A'].push_back(v - 'A'); G[v - 'A'].push_back(u - 'A'); }
        }
    }
    void dfs_pre(int m)
    {
        vis[m] = 1;
        int num = G[m].size();
        for(int i = 0; i < num; ++i)
        if(! vis[ G[m][i] ]) dfs_pre(G[m][i]);
    }
    int dfs(int m,int tag)
    {
        int i;
        vis2[m] = 1;
        if(m == tag) return 1;
        int num = G[m].size();
        for(i = 0; i < num ; ++i)
        if(! vis2[ G[m][i] ] )  { if(dfs(G[m][i],tag)) return 1; }
        if(i >= num ) return 0;
    }
    void solve()
    {
        int i;
        read_graph();
        for(i=0 ;i < 26 ; ++i)//扫一遍,若某结点之前标记了,其邻接点也是成立的
        if(vis[i]) dfs_pre(i);
        cin >> x;
        while(x --)
        {
            cin >> t;
            if(t == 1) {
                cin >> k;
            if(vis[k - 'A']) cout << "yes" <<endl;
            else cout << "no" <<endl;
            continue;
            }
            if(t == 2){
                memset(vis2, 0 ,sizeof vis2 );
                cin >> u >> v;
                if(u == v) { cout << "yes" <<endl; continue; }//特判
                int num = G[u - 'A'].size();
                for(i = 0; i < num; ++i)
                if(! vis2[ G[u - 'A'][i] ]) { if(dfs(G[u - 'A'][i],v - 'A')) break; }
                if(i >= num) cout << "no" <<endl;
                else cout << "yes" <<endl;
            }
            else{
                memset(vis2, 0 ,sizeof vis2 );
                cin >> u >> v;
                if(u == v) { cout << "yes" <<endl; continue; }//特判
                int leap , leap2;
                int num, num2;
                leap = leap2 = 0;
                num = G[u - 'A'].size();
                num2 = G[v - 'A'].size();
                for(i = 0; i < num; ++i)//从 u->v  扫一遍u的邻接点
                if(! vis2[ G[u - 'A'][i] ]) { if(leap = dfs(G[u - 'A'][i],v - 'A')) break; }
                memset(vis2 ,0 ,sizeof vis2);
                for(i = 0; i< num2 ; ++i)//从 v->u 扫一遍v的邻接点
                if(! vis2[ G[v - 'A'][i] ]) { if(leap2 = dfs(G[v - 'A'][i],u - 'A')) break; }
                if(leap && leap2) cout << "yes" <<endl;
                else cout << "no" <<endl;
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(0);
        solve();
        return 0;
    }
    /*坑爹例子
    0
    1
    3    Z    Z
    ans:yes
    */
    View Code
  • 相关阅读:
    绘图QPainter-画刷
    绘图QPainter-画笔
    pyqt5-多线程QThread类
    升级时出现错误的解决办法
    打包pyinstaller
    多文档界面QMdiArea
    停靠窗口QDockWidget
    堆叠窗口QStackedWidget
    VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结
    【一】ODB
  • 原文地址:https://www.cnblogs.com/orchidzjl/p/4433393.html
Copyright © 2011-2022 走看看