Codeforces Round #390 (Div. 2) C. Vladik and chat(dp)
http://codeforces.com/contest/754/problem/C
2 seconds
256 megabytes
standard input
standard output
Recently Vladik discovered a new entertainment — coding bots for social networks. He would like to use machine learning in his bots so now he want to prepare some learning data for them.
At first, he need to download t chats. Vladik coded a script which should have downloaded the chats, however, something went wrong. In particular, some of the messages have no information of their sender. It is known that if a person sends several messages in a row, they all are merged into a single message. It means that there could not be two or more messages in a row with the same sender. Moreover, a sender never mention himself in his messages.
Vladik wants to recover senders of all the messages so that each two neighboring messages will have different senders and no sender will mention himself in his messages.
He has no idea of how to do this, and asks you for help. Help Vladik to recover senders in each of the chats!
The first line contains single integer t (1 ≤ t ≤ 10) — the number of chats. The t chats follow. Each chat is given in the following format.
The first line of each chat description contains single integer n (1 ≤ n ≤ 100) — the number of users in the chat.
The next line contains n space-separated distinct usernames. Each username consists of lowercase and uppercase English letters and digits. The usernames can't start with a digit. Two usernames are different even if they differ only with letters' case. The length of username is positive and doesn't exceed 10 characters.
The next line contains single integer m (1 ≤ m ≤ 100) — the number of messages in the chat. The next m line contain the messages in the following formats, one per line:
- <username>:<text> — the format of a message with known sender. The username should appear in the list of usernames of the chat.
- <?>:<text> — the format of a message with unknown sender.
The text of a message can consist of lowercase and uppercase English letter, digits, characters '.' (dot), ',' (comma), '!'(exclamation mark), '?' (question mark) and ' ' (space). The text doesn't contain trailing spaces. The length of the text is positive and doesn't exceed 100 characters.
We say that a text mention a user if his username appears in the text as a word. In other words, the username appears in a such a position that the two characters before and after its appearance either do not exist or are not English letters or digits. For example, the text "Vasya, masha13 and Kate!" can mention users "Vasya", "masha13", "and" and "Kate", but not "masha".
It is guaranteed that in each chat no known sender mention himself in his messages and there are no two neighboring messages with the same known sender.
Print the information about the t chats in the following format:
If it is not possible to recover senders, print single line "Impossible" for this chat. Otherwise print m messages in the following format:
<username>:<text>
题意:
现在有n个人,然后有m句话,有些话不知道说话人是谁,现在我们要去找能去说这句话的人,要求是前后两句话说话的人不能相同,如果后面话中出现的名字也不能作为说话人。输出一种情况即可。
思路:
用 f【i】【j】=1 表示 j 可以说第 i 句话,g【】【】用来记录路径,用于最后的输出。
先对每句话进行处理,分离出说话人和后面话中所包含的说话人。对于这句话,我们找到上一句话可以说话的人,在此基础上,判断接下来可以说话的人有谁。
话说这个字符串的处理还真是麻烦啊....
参考了http://blog.csdn.net/h1021456873/article/details/54947748的代码。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn=+; int n, m; int f[maxn][maxn]; //f[i][j]表示j可以说第i句话
int g[maxn][maxn]; //记录状态,用于输出(相当于记录路径) string name[maxn];
string str[maxn]; //第i句话
string re[maxn]; //记录第i句话,不包括说话人 map<string, int> ID; void print(int m, int x)
{
if(m==) return;
print(m-,g[m][x]);
cout<<name[x]<<re[m-]<<endl;
} int main()
{
//freopen("in.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--)
{
ID.clear();
bool flag=true; scanf("%d",&n);
for(int i=;i<n;i++)
{
cin>>name[i];
ID[name[i]]=i;
}
scanf("%d",&m);
getchar();
for(int i=;i<m;i++)
{
getline(cin, str[i]);
re[i].clear();
} memset(f,,sizeof(f));
memset(g,,sizeof(g));
f[][n]=; for(int i=;i<m;i++)
{
string user, buf = str[i];
int p=;
for(; p<buf.size() && buf[p]!=':'; p++)
{
user+=buf[p];
} int q = p;
while(q<buf.size())
{
re[i]+=buf[q++];
} set<int> mention; //记录当前这句话不能说的人
while(p<buf.size())
{
string word;
while(p<buf.size() && isalnum(buf[p]))
{
word+=buf[p++];
}
if(ID.count(word)) mention.insert(ID[word]);
if(p<buf.size()) p++;
} if(user=="?")
{
for(int j=;j<=n;j++)
{
if(!f[i][j]) continue; //寻找上一句可以说的人
for(int k=;k<n;k++)
{
if(mention.count(k) || k==j) continue; //不在set中并且和上一句说话的不是同一个人
f[i+][k]=;
g[i+][k]=j;
}
}
}
else
{
if(!ID.count(user))
{
flag=false;
}
int id = ID[user];
if(mention.count(id))
{
flag=false;
}
else
{
for(int j=;j<=n;j++)
{
if(!f[i][j]) continue;
if(id!=j)
{
f[i+][id]=;
g[i+][id]=j;
}
}
}
}
} if(flag==true)
{
int x=-;
for(int j=;j<n;j++)
if(f[m][j]) x=j; if(x==-) puts("Impossible");
else print(m,x);
}
else puts("Impossible");
}
return ;
}
Codeforces Round #390 (Div. 2) C. Vladik and chat(dp)的更多相关文章
- Codeforces Round #267 (Div. 2) C. George and Job(DP)补题
Codeforces Round #267 (Div. 2) C. George and Job题目链接请点击~ The new ITone 6 has been released recently ...
- Codeforces Round #605 (Div. 3) D. Remove One Element(DP)
链接: https://codeforces.com/contest/1272/problem/D 题意: You are given an array a consisting of n integ ...
- Codeforces Round #651 (Div. 2) E. Binary Subsequence Rotation(dp)
题目链接:https://codeforces.com/contest/1370/problem/E 题意 给出两个长为 $n$ 的 $01$ 串 $s$ 和 $t$,每次可以选择 $s$ 的一些下标 ...
- Codeforces Round #321 (Div. 2) D Kefa and Dishes(dp)
用spfa,和dp是一样的.转移只和最后一个吃的dish和吃了哪些有关. 把松弛改成变长.因为是DAG,所以一定没环.操作最多有84934656,514ms跑过,实际远远没这么多. 脑补过一下费用流, ...
- Codeforces Round #267 (Div. 2) C. George and Job (dp)
wa哭了,,t哭了,,还是看了题解... 8170436 2014-10-11 06:41:51 njczy2010 C - George and Jo ...
- Codeforces Round #184 (Div. 2) E. Playing with String(博弈)
题目大意 两个人轮流在一个字符串上删掉一个字符,没有字符可删的人输掉游戏 删字符的规则如下: 1. 每次从一个字符串中选取一个字符,它是一个长度至少为 3 的奇回文串的中心 2. 删掉该字符,同时,他 ...
- Codeforces Round #556 (Div. 2) - C. Prefix Sum Primes(思维)
Problem Codeforces Round #556 (Div. 2) - D. Three Religions Time Limit: 1000 mSec Problem Descripti ...
- Codeforces Round #394 (Div. 2) E. Dasha and Puzzle(分形)
E. Dasha and Puzzle time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- Codeforces Round #394 (Div. 2) C.Dasha and Password(暴力)
http://codeforces.com/contest/761/problem/C 题意:给出n个串,每个串的初始光标都位于0(列)处,怎样移动光标能够在凑出密码(每个串的光标位置表示一个密码的字 ...
随机推荐
- WCF(一) 创建第一个WCF
定义服务契约-创建宿主程序-创建客户端程序访问服务 namespace HelloService { /// <summary> /// 服务契约 /// </summary> ...
- 香港主机Squid+Stunnel代理搭建
1.说明 Squid,代理软件 Stunnel,数据包加密(貌似如果数据不加密,客户端的数据流无法传到squid服务端,原因你懂的!) 2.Squid安装略 3.安装完squid后需要以下操作 a.生 ...
- 310实验室OTL问题
1.首先是下载OTL文件包,网址是:github.com/O-T-L,可以直接点击网页上的下载链接,也可以使用unlix命令,git clone https://github.com/O-T-L/OT ...
- postgresql----SELECT
示例1.简单查询 使用*查询表所有的字段,也可以指定字段名查询 test=# select * from tbl_insert; a | b ---+---- | sd | ff ( rows) te ...
- java 常见几种发送http请求案例
import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java ...
- 服务器和客户端的交互方式(Socket,http协议)和各自特点适用范围
1 数据传输方式 1.1 Socket传输的定义和其特点 所谓socket通常也称作"套接字",实现服务器和客户端之间的物理连接,并进行数据传输,主要有UDP和TCP两个协议.S ...
- 修改nginx的http响应头server字段
信息泄露类型:HTTP服务器响应头Server字段信息泄露 示例: 解决: 需要重新对nginx编译安装: [root@localhost ~]# tar zxvf nginx-1.8.1.tar.g ...
- nodejs学习笔记Node.js 调试命令
3.4 调试 47 下面是一个简单的例子: $ node debug debug.js < debugger listening on port 5858 connecting ...
- Windows中杀死某个端口的进程
最近写项目,总是出现端口被占用的问题,原来傻傻的把电脑重启一下,终于有一天受不了了,想要想办法解决.刚开始从网上找了好多教程,发现不行.开始自己尝试,终于,成功的将占用端口的进程杀掉.在此记录下过程( ...
- 【Python】Python 打印和输出更多用法。
Python 打印和输出 简述 在编程实践中,print 的使用频率非常高,特别是程序运行到某个时刻,要检测产生的结果时,必须用 print 来打印输出. 关于 print 函数,前面很多地方已经提及 ...