zoukankan      html  css  js  c++  java
  • upc组队赛4 TV Show Game 【2-SAT】

    TV Show Game

    题目描述

    Mr. Dajuda, who is famous for a TV show program, occasionally suggests an interesting game for the audience and gives them some gifts as a prize. The game he suggested this week can be explained as follows.

    The k(> 3) lamps on the stage are all turned off at the beginning of the game. For convenience, lamps are numbered from 1 to k. Each lamp has a color, either red or blue. However, the color of a lamp cannot be identified until it is turned on. Game participants are asked to select three lamps at random and to guess the colors of them. Then each participant submits a paper on which the predicted colors of selected lamps are recorded to Mr. Dajuda, the game host. When all the lamps are turned on, each participant checks how many predicted colors match the actual colors of the lamps. If two or more colors match, he/she will receive a nice gift as a prize.

    Mr. Dajuda prepared a special gift today. That is, after reviewing all the papers received from the game participants he tries to adjust the color of each lamp so that every participant can receive a prize if possible.

    Given information about the predicted colors as explained above, write a program that determines whether the colors of all the lamps can be adjusted so that all the participants can receive prizes.

    输入

    Your program is to read from standard input. The input starts with a line containing two integers, k and n (3 < k ≤ 5,000, 1 ≤ n ≤ 10,000), where k is the number of lamps and n the number of game participants. Each of the following n lines contains three pairs of (l, c), where l is the lamp number he/she selected and c is a character, either B for blue or R for red, which denotes the color he/she guessed for the lamp. There is a blank between l and c and each pair of (l, c) is separated by a blank as well as shown in following samples.

    输出

    Your program is to write to standard output. If it is possible that all the colors can be adjusted so that every participant can receive a prize, print k characters in a line. The ith character, either B for blue or R for red represents the color of the ith lamp. If impossible, print -1. If there are more than one answer, you can print out any of them.

    样例输入

    7 5
    3 R 5 R 6 B
    1 B 2 B 3 R
    4 R 5 B 6 B
    5 R 6 B 7 B
    1 R 2 R 4 R
    

    样例输出

    BRRRBBB
    

    题意

    有k个灯,5个嘉宾,每个嘉宾会选择3个灯进行猜颜色(只有红色和蓝色),猜中两个以上有奖,问怎么设置灯的颜色能使所有嘉宾都能得奖。

    题解

    比赛的时候 和zn一起 写的暴搜 调试改错 花了两个小时吧 终于能过样例了 然而结果肯定是超时了

    正解是 建立图论里的2-SAT模型

    关于什么是2 - SAT 可以看看大神的讲解 https://blog.csdn.net/jarjingx/article/details/8521690

    研究了一天多...目前还是半知半解,等完全明白了回来更新

    照着题解写了个AC代码

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    #define rep(i,a,n) for(int i=a;i<n;++i)
    #define read(x) scanf("%d",&x)
    #define read2(x,y) scanf("%d%d",&x,&y)
    #define pb push_back
    #define mp make_pair
    typedef pair<int,int> P;
    typedef long long ll;
    const int maxn = 10005;
    const int maxm = 5005;
    int T;
    int n,k;
    int tmp;
    int vis[maxn * 2];
    vector<int> sb[maxn],dd[maxn];
    map<char,int>c;
    stack<int> st;
    
    int dfs(int u){
      if(vis[u]) return 1;
      if(vis[u ^ 1]) return 0;
      vis[u] = 1;
      st.push(u) ;
      for(int i = 0; i < dd[u].size(); i++){
        int v = dd[u][i];
        for(int j = 0; j < sb[v].size(); j++){
          int g = sb[v][j];
          if(u != g){
            if(!dfs(g ^ 1))  return 0;
          }
        }
      }
      return 1;
    }
    
    int _2sat(){
      memset(vis,0,sizeof vis);
      for(int i = 2; i <= k * 2; i += 2){
        if(vis[i] || vis[i ^ 1]) continue;
        while(!st.empty())  st.pop();
        if(!dfs(i)) {
          while(!st.empty()){
            vis[st.top()] = 0;
            st.pop();
          }
          if(!dfs(i ^ 1)) return 0;
        }
      }
      return 1;
    }
    
    int main()
    {
      c['R'] = 0;
      c['B'] = 1;
      int pos;
      char col;
      read2(k,n);
      for(int i = 1; i < maxn ;i ++) {
        dd[i].clear();
        sb[i].clear();
      }
      for(int i = 1; i <= n; i++){
          for(int j = 0; j < 3; j++){
              scanf("%d %c",&pos,&col);
              tmp = pos * 2 + (c[col] ^ 1);
              sb[i].pb(tmp);
              dd[tmp].pb(i);
          }
      }
      if(_2sat()){
        for(int i = 1; i <= k; i++){
          if(vis[i * 2]) printf("R");
          else printf("B");
        }
        printf("
    ");
      }
      else printf("-1");
      return 0;
    }
    
  • 相关阅读:
    泛型程序设计详解(一)
    面向对象三大特性-----封装、继承、多态
    委托与事件-委托事件案例(三)
    委托与事件-事件详解(二)
    委托与事件-委托详解(一)
    抽象类及接口详解
    基础类型详解下
    C#类型详解
    【JVM】-- JVM内存结构
    【redis】-- redis的持久化(作为数据库)
  • 原文地址:https://www.cnblogs.com/llke/p/10799987.html
Copyright © 2011-2022 走看看