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("\n");
  }
  else printf("-1");
  return 0;
}

转载于:https://www.cnblogs.com/llke/p/10799987.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值