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(列)处,怎样移动光标能够在凑出密码(每个串的光标位置表示一个密码的字 ...
随机推荐
- List<String>和String相互转换
List<String>转String String Message=""; for (String msg : message) { Message = Messag ...
- localstorage - HTML 5 Web 存储总结---【巷子】
001.localStorage概念 在html5中,新加入了一个localStorage特性,这个特性主要是用来作为本地存储,解决了cookie存储空间不足的问题(cookie中每条cookie存储 ...
- Apache的配置详解,最好的Apache配置文档
http://blog.csdn.net/apple_llb/article/details/50253889 Apache的配置由httpd.conf文件配置,因此下面的配置指令都是在httpd.c ...
- CommonHelper 公共类
public static class CommonHelper 公共帮助类 using System.Collections.Generic; using System.Linq; using ...
- poj2376 Cleaning Shifts【线段树】【DP】
Cleaning Shifts Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 32561 Accepted: 7972 ...
- Javascript计算星座
今天看群里一哥们折腾得挺热乎,手痒随便写了一个DEMO,供初学者参考. 重点,写程序先定注释,明确思路后再写具体代码. //星座定义 var constellations = [ {"Sta ...
- 洛谷P1373 小a和uim之大逃离 dp
正解:dp 解题报告: 传送门! 同样是看到列表发的题解就想着跟着做下dp的题目趴 然后发现还挺难的,,,反正我只大概想到怎么转移但是初始化什么的都不会TT 所以还是大概说下QAQ 首先可以想到设f[ ...
- Redis缓冲区设置
对于Redis服务器的输出(也就是命令的返回值)来说,其大小通常是不可控制的.有可能一个简单的命令,能够产生体积庞大的返回数据.另外也有可能因为执行了太多命令,导致产生返回数据的速率超过了往客户端发送 ...
- 寻找最小(最大)的k个数
题目描述:输入n个整数,输出其中最小的k个元素. 例如:输入1,2,3,4,5,6,7,8这8个数字,则最小的4个数字为1,2,3,4. 思路1:最容易想到的方法:先对这个序列从小到大排序,然后输出前 ...
- MySQL创建索引命令
MySQL索引类型 普通索引 创建索引的方式 -- 直接新建索引 CREATE INDEX indexName ON mytable(username(length)) -- 修改表结构新建索引 AL ...