题目链接:http://codeforces.com/problemset/problem/495/C

题目意思:给出一串只有三种字符( ')','(' 和 '#')组成的字符串,每个位置的这个字符 '#'可以替换成不少于 1 个的 ')',问如何对每个'#'进行替换,使得对于字符串的任意一个位置, ')' 的数量始终不大于'(' 的数量。注意,'#'被替换成')'的总数以及原先有的')'的数量之和 == '(' 的总数。

  花了两个晚上的一点时间,今天在图书馆里终于想到解决方案了,大感动 ~~~~ >__<

/********************************************* (错误思路请忽略= =)

  第一个晚上做的时候,只知道最好的填法就是,除了最后一个'#'之外,其他都替换为一个 ')',最后一个就根据公式: 数量 '(' -  数量 ')' - (总的'#'数 - 1)  来填入。

  但是问题是,如何确定有解。我当时很天真地以为,如果 '(' == ')' 但是'#'还有剩('#' > 0)就无解,test7:#)))) 证明此想法是错的,本来答案是-1,我程序输出 -4,因为这个判断是有缺陷的,排除不了这种情况。后来干脆直接保存每个位置的'(' (cnt[]) 和  ')'(cnt1[])的数量还有 '#'的数量,如果是'(',cnt[i] = cnt[i-1]+1,cnt1[i] = cnt[i-1];如果是')',cnt1[i] = cnt1[i-1]+1,cnt[i] = cnt[i-1];如果是'#',cnt[i] = cnt[i-1],cnt1[i] = cnt1[i-1]。'(', ')', '#'总数量分别对应c1, c2, c0,然后加多一个check()函数来判断如果cnt[i] < cnt1[i] 就 返回false,我只能说:有点不知所谓 = =....因为压根就没有考虑'#' 的值!不知道'#'具体填什么【test12 ##((((((() 】。改改改接着就是test14........噩梦啊~~~~煎熬啊

  **********************************************/

  早上重新想过,终于有头绪了。我的做法应该叫做所谓的反证法吧~~~~容易知道最保守最可行的方法就是:除了最后一个'#'之外的所有 '#' 都替换为 一个')'。

  设两个整型数tot 和c(初始值都为 0, c 用来保存'#'的数量),一个数组vis[],保存每个'#'的位置的替换个数,遍历一遍数组s[i]

  if 【'('】 tot++

  if 【')'】 tot--

  if 【'#'】 c++, vis[i] = 1

  然后反向遍历数组s[i],找出最后一个'#'的位置,使得vis[i] = tot - (c-1)。但是前期要做一个判断工作,tot-(c-1) <= 0是无解的!,它专门处理 '(' == ')',c >= 1 的情况(类似(#),或者 #)。

  最后当然就是判断无解情况啦。开一个整数 cnt = 0,从前往后遍历数组s[],

  if 【'('】 cnt++

  if 【')'】 cnt--

  if 【'#'】 cnt -= vis[i]

  需要检查每个位置的cnt的值,if (cnt < 0) 就返回false。即表示 ) > ( ,不满足题目要求。

  最后返回true的情况是 cnt == 0,这样才能保证    '#' 替换为 ')' 以及本来存在的 ')' 的数量之和 等于 ‘(' 的数量

  如果经得起 check() 函数的考验,那么就输出解。

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std; const int maxn = 1e5 + ;
char s[maxn];
int vis[maxn], len; bool check(char s[])
{
int cnt = ;
for (int i = ; i < len; i++)
{
if (s[i] == '(')
cnt++;
else if (s[i] == ')')
cnt--;
else // #
cnt -= vis[i];
if (cnt < ) // 任意位置都要保证 ')' <= '('
return false;
}
if (cnt == )
return true;
return false;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE while (scanf("%s", s) != EOF)
{
memset(vis, , sizeof(vis)); len = strlen(s);
int tot = , c = ;
for (int i = ; i < len; i++)
{
if (s[i] == '(')
tot++;
else if (s[i] == ')')
tot--;
else // #
{
c++;
vis[i] = ;
}
}
if (tot-(c-) <= )
printf("-1\n");
else
{
int last = tot - (c-); // 最后一个 # 的赋值,至少要为1
for (int i = len-; i >= ; i--)
{
if (s[i] == '#')
{
vis[i] = last;
break;
}
}
if (!check(s))
printf("-1\n");
else
{
for (int i = ; i <= c-; i++)
printf("1\n");
printf("%d\n", last);
}
}
}
return ;
}

codeforces 495C. Treasure 解题报告的更多相关文章

  1. codeforces 31C Schedule 解题报告

    题目链接:http://codeforces.com/problemset/problem/31/C 题目意思:给出 n 个 lessons 你,每个lesson 有对应的 起始和结束时间.问通过删除 ...

  2. codeforces 499B.Lecture 解题报告

    题目链接:http://codeforces.com/problemset/problem/499/B 题目意思:给出两种语言下 m 个单词表(word1, word2)的一一对应,以及 profes ...

  3. codeforces 490B.Queue 解题报告

    题目链接:http://codeforces.com/problemset/problem/490/B 题目意思:给出每个人 i 站在他前面的人的编号 ai 和后面的人的编号 bi.注意,排在第一个位 ...

  4. CodeForces 166E -Tetrahedron解题报告

    这是本人写的第一次博客,学了半年的基础C语言,初学算法,若有错误还请指正. 题目链接:http://codeforces.com/contest/166/problem/E E. Tetrahedro ...

  5. codeforces 489A.SwapSort 解题报告

    题目链接:http://codeforces.com/problemset/problem/489/A 题目意思:给出一个 n 个无序的序列,问能通过两两交换,需要多少次使得整个序列最终呈现非递减形式 ...

  6. codeforces 485A.Factory 解题报告

    题目链接:http://codeforces.com/problemset/problem/485/A 题目意思:给出 a 和 m,a 表示第一日的details,要求该日结束时要多生产 a mod ...

  7. codeforces 483A. Counterexample 解题报告

    题目链接:http://codeforces.com/problemset/problem/483/A 题目意思:给出一个区间 [l, r],要从中找出a, b, c,需要满足 a, b 互质,b, ...

  8. codeforces 479C Exams 解题报告

    题目链接:http://codeforces.com/problemset/problem/479/C 题目意思:简单来说,就是有个人需要通过 n 门考试,每场考试他可以选择ai, bi 这其中一个时 ...

  9. codeforces 479B Towers 解题报告

    题目链接:http://codeforces.com/problemset/problem/479/B 题目意思:有 n 座塔,第 i 座塔有 ai 个cubes在上面.规定每一次操作是从最多 cub ...

随机推荐

  1. twoSum

    Given an array of integers, find two numbers such that they add up to a specific target number. The ...

  2. php 经典的算法题你懂的

    有5个人偷了一堆苹果,准备在第二天分赃.晚上,有一人遛出来,把所有菜果分成5份,但是多了一个,顺手把这个扔给树上的猴了,自己先拿1/5藏了.没想到其他四人也都是这么想的,都如第一个人一样分成5份把多的 ...

  3. jQuery源码-dom操作之jQuery.fn.html

    写在前面 前面陆陆续续写了jQuery源码的一些分析,尽可能地想要cover里面的源码细节,结果导致进度有些缓慢.jQuery的源码本来就比较晦涩,里面还有很多为了解决兼容问题很引入的神代码,如果不g ...

  4. git之tag

    参考:git命令之git tag 给当前分支打标签 1.git tag //查看已有标签 2.创建本地标签 git tag tag_name  //创建标签  git tag -a v0.1.2 -m ...

  5. this.getServletContext().getRealPath("WEB-INF");

    this.getServletContext().getRealPath("WEB-INF");

  6. DOM之操作技术

    1.1 动态脚本 动态加载的外部JS文件能够立即运行.难点在于如何知道脚本加载完成了?可以通过事件来检测.IE对待<script>元素特殊性,不允许DOM访问其子节点.使用元素的text属 ...

  7. BZOJ1030——文本生成器

    给你若干给字符串,再给你一个m,问长度是m的字符串中包含给定字符串的数量mod 10007是多少 这个拿过来啥思路也没有,后来还是看了题解,才知道,原来,原来....那个带fail的Trie还可以搞别 ...

  8. js计算24点

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. iOS中多线程原理与runloop介绍

    一.线程概述 有些程序是一条直线,起点到终点:有些程序是一个圆,不断循环,直到将它切断.直线的如简单的Hello World,运行打印完,它的生命周期便结束了,像昙花一现那样:圆如操作系统,一直运行直 ...

  10. [POJ1068]Parencodings

    [POJ1068]Parencodings 试题描述 Let S = s1 s2...s2n be a well-formed string of parentheses. S can be enco ...