uva live 7637 Balanced String (贪心)

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5659

题意:

  你有一个只包含"(" 和 ")" 的串,每一个位置有个数值,这个数值是当前的左括号-右括号的值。

  例:()() 数值就是1010。

  给你一个打乱了的数值,要你构造出字典序最小的字符串。

题解:

  因为左括号比右括号小,所以我们要尽量的选择左括号,选择左括号会使得数值增大,如果这个数值不能继续增大了我们就只能选择右括号。

  记得要初始化

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <string>
 5 #include <algorithm>
 6 #include <cmath>
 7 #include <vector>
 8 #include <queue>
 9 #include <map>
10 #include <stack>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 typedef unsigned long long uLL;
15 #define ms(a, b) memset(a, b, sizeof(a))
16 #define pb push_back
17 #define mp make_pair
18 #define eps 0.0000000001
19 #define IOS ios::sync_with_stdio(0);cin.tie(0);
20 const LL INF = 0x3f3f3f3f3f3f3f3f;
21 const int inf = 0x3f3f3f3f;
22 const int mod = 1e9+7;
23 const int maxn = 100000+10;
24 int a[maxn];
25 int num[maxn];
26 int last[maxn];
27 int ans[maxn];
28 void solve()
29 {
30     ms(num, 0);
31     ms(last, 0);
32     int n;scanf("%d", &n);
33     for(int i = 0;i<n;i++)  scanf("%d", &a[i]);
34     for(int i = 0;i<n;i++){
35         if(a[i]<0){
36             printf("invalid");return;
37         }
38     }
39     for(int i = 0;i<n;i++){
40         num[a[i]]++;
41     }
42     last[0]=0;
43     for(int i=1;i<=n;i++){
44         if(num[last[i-1]+1]){
45             last[i] = last[i-1]+1;
46             ans[i] = 1;
47             num[last[i-1]+1]--;
48         }
49         else if(num[last[i-1]-1]){
50             last[i] = last[i-1]-1;
51             ans[i] = 0;
52             num[last[i-1]-1]--;
53         }
54         else{
55             printf("invalid");return;
56         }
57     }
58     if(ans[n]==0){
59         for(int i = 1;i<=n;i++)
60             if(ans[i]==1)  printf("(");
61             else    printf(")");
62     }else{
63         printf("invalid");return;
64     }
65 }
66 int main() {
67 #ifdef LOCAL
68     freopen("input.txt", "r", stdin);
69 //        freopen("output.txt", "w", stdout);
70 #endif
71 //    IOS
72     int t;scanf("%d", &t);
73     int cnt = 1;
74     while(t--){
75         printf("Case %d: ", cnt++);
76         solve();
77         printf("\n");
78     }
79     return 0;
80 }

时间: 2024-10-05 10:44:08

uva live 7637 Balanced String (贪心)的相关文章

UVaLive 7637 Balanced String (构造)

题意:给定一个括号的序列,原先的序列是碰到左括号加1,碰到右括号减1,然后把序列打乱,让你找出字典序最小的一个答案. 析:直接从第一个括号判断就好了,优先判断左括号,如果不行就加右括号. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cma

uva:10670 - Work Reduction(贪心)

题目:10670 - Work Reduction 题目大意:给出n, m, L.n代表老板给的全部的paperworks的数量,m代表最终剩下的数量,L代表由这么多家公司需要你来计算最小的花费. 解题思路: 1.L家公司l行.每行由公司的名字 :A,B: A代表一份paperwork需要的money,B则代表帮你减少到总共的paperworks的数量一半要话费的money.注意这里是你手头上有的paperworks而不是老板要求你完成的数量,之前在这里卡了好久.还有减半不能导致最终的数量小于m

uva:10602 - Editor Nottoobad(贪心)

题目:10602 - Editor Nottoobad 题目大意:有一个机子它由press的动作还有copy和delete字符的动作.给一组字符串,问要输入这样的一组字符串,最少要执行的press动作. 解题思路:将这一组字符串按照ascall码排序后,这样前后两个字符串的相似度是比较高的.然后后一个字符串和前一个字符串相比,看有多少相同的可以copy,就只要统计一下不相同的字符个数.这题比较迷惑人的是题目一直说要求第一个字符串一定要先执行press动作,但是输出却可以任意给一种,不一定是要第一

UVA 1379 - Pitcher Rotation(DP + 贪心)

题目链接:1379 - Pitcher Rotation 题意:n个人,m个敌人,去比赛,有得分,n个人可以重复比,但是每次比完要休息4天,问最大得分 思路:dp[i][j][k][l][x] 表示第场比赛,前一天为j,两天为k,三天为l,四天为x,的最大得分,然后由于只有每个人5天就能用一次,所以对于每个人来说,只有得分前5的会被使用上,所以后4维状态只需要5^4,进行状态转移,不用比赛的情况分开考虑,还有这题内存有限,要用滚动数组优化不然会RE 代码: #include <stdio.h>

uva 1521 - GCD Guessing Game(贪心)

题目链接:uva 1521 - GCD Guessing Game 题目大意:给定一个数N,现在又一个数x,在1~N之间,现在每次可以猜一个数a,返回gcd(x,a),问说最少猜几次可以确定x. 解题思路:其实就将1~N里面的素数都要考虑一遍,因为有一个N的限制,所以每次选出来的素数的积不大于N即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const

uva 10026 Shoemaker&#39;s Problem(贪心+排序)

虽然是个水题,但是在一些细节上wa了几次,好像不支持'\b'退格符号,我用在了输出空格那,结果wa了...白白 wa了几次...题意是看的题解..今天只写了两道题,速度有点慢,得加快了,以后得先认真读懂题目,题目读懂了 就相当于做出来一半然后仔细动脑想想,有想法了再敲,不能盲目的做题.另外,热烈祝贺今天c++ primer看到 了100页 思路: 这道题是让给的数据是每件工作需要做的天数和每耽误一天所需要的费用,让求一个序列使得付费最小,如果有相同答 案把字典树最小的输出...输出的是序号,该件

uva 1016 - Silly Sort(置换+贪心)

题目链接:uva 1016 - Silly Sort 题目大意:给定一个长度为n的序列,每次操作可以交换任意两个数的位置,代价为两个数的和,求最小代价,将序列排成有序的. 解题思路:给定序列根据数的大小映射成一个置换,分解置换的循环,对于每个循环中,肯定是用值最小的逐个去交换的代价最小,但是要考虑,可以将最小的值与序列中最小值交换,用它代替去交换,最后再换回来.取两种情况中最优的. #include <cstdio> #include <cstring> #include <

uva 714 - Copying Books(贪心 最大值最小化 二分)

题目描述开头一大堆屁话,我还仔细看了半天..其实就最后2句管用.意思就是给出n本书然后要分成k份,每份总页数的最大值要最小.问你分配方案,如果最小值相同情况下有多种分配方案,输出前面份数小的,就像字典序输出从小到大一样的意思. 这里用到贪心的方法,定义f(x)为真的条件是满足x为最大值使n本书分成k份,那么就是求x的最小值.如何确定这个x就是用的二分法,x一定大于0小于所有值的合,不断的二分再判断是否成立,成立就取左半边,不成立说明太小了就取右半边,写的时候还是没有把二分法理解透彻,我还怕会丢失

uva 1368 - DNA Consensus String(字符串处理)

uva 1368 - DNA Consensus String Figure 1. DNA (Deoxyribonucleic Acid) is the molecule which contains the genetic instructions. It consists of four different nucleotides, namely Adenine, Thymine, Guanine, and Cytosine as shown in Figure 1. If we repre