2015/3/31/ Codeforces Round #297 (Div. 2)

来源:互联网 发布:2017淘宝开店规则 编辑:程序博客网 时间:2024/06/14 23:56

A. Vitaliy and Pie
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

After a hard day Vitaly got very hungry and he wants to eat his favorite potato pie. But it's not that simple. Vitaly is in the first room of the house with n room located in a line and numbered starting from one from left to right. You can go from the first room to the second room, from the second room to the third room and so on — you can go from the (n - 1)-th room to the n-th room. Thus, you can go to room x only from room x - 1.

The potato pie is located in the n-th room and Vitaly needs to go there.

Each pair of consecutive rooms has a door between them. In order to go to room x from room x - 1, you need to open the door between the rooms with the corresponding key.

In total the house has several types of doors (represented by uppercase Latin letters) and several types of keys (represented by lowercase Latin letters). The key of type t can open the door of type T if and only if t and T are the same letter, written in different cases. For example, key f can open door F.

Each of the first n - 1 rooms contains exactly one key of some type that Vitaly can use to get to next rooms. Once the door is open with some key, Vitaly won't get the key from the keyhole but he will immediately run into the next room. In other words, each key can open no more than one door.

Vitaly realizes that he may end up in some room without the key that opens the door to the next room. Before the start his run for the potato pie Vitaly can buy any number of keys of any type that is guaranteed to get to room n.

Given the plan of the house, Vitaly wants to know what is the minimum number of keys he needs to buy to surely get to the room n, which has a delicious potato pie. Write a program that will help Vitaly find out this number.

Input

The first line of the input contains a positive integer n (2 ≤ n ≤ 105) — the number of rooms in the house.

The second line of the input contains string s of length n - 2. Let's number the elements of the string from left to right, starting from one.

The odd positions in the given string s contain lowercase Latin letters — the types of the keys that lie in the corresponding rooms. Thus, each odd position i of the given string s contains a lowercase Latin letter — the type of the key that lies in room number (i + 1) / 2.

The even positions in the given string contain uppercase Latin letters — the types of doors between the rooms. Thus, each even positioni of the given string s contains an uppercase letter — the type of the door that leads from room i / 2 to room i / 2 + 1.

Output

Print the only integer — the minimum number of keys that Vitaly needs to buy to surely get from room one to room n.

Sample test(s)
input
3aAbB
output
0
input
4aBaCaB
output
3
input
5xYyXzZaZ
output
2

这道题目的大致意思是:

就是一个人一开始站在第一个房间里,然后有n个房间,只能从第n-1个房间到达第n个房间。每个房间都有一种类别的钥匙(用小写字母表示),要打开相对应的门(门是用大写字母表示)。并且没把钥匙只能使用一次。这里注意,每个房间里藏的钥匙也许不是对应于下一个房间的钥匙,但是你可以把它先拿走,然后万一下面有房间要用到这把钥匙的话,那么就可以去使用它了。但是有时候会出现你有可能到不了最后的那个房间,所以题目叫你求的是如果你必须到达那个房间,你要至少要事先准备多少把钥匙。

一开始我想的是每次for一遍寻找后面的房间是否有符合前面房间不匹配的钥匙的,但是这样子的时间复杂度是n^2,直接TLE.

后来看了题解,知道了一个新的方法,那么就是每次都把当前那种类型的钥匙给存在一个数组中,然后再与后面读入的房间号(把它转换为小写,然后比较是否能匹配,如果能匹配,那么就减1,否则,那么还要再新配一把钥匙)

#include<stdio.h>#include<string.h>char a[222222];int num1[222222]={0};int main(){    int n,i,j,k;    int len,ans=0;    scanf("%d",&n);    scanf("%s",a);    len=strlen(a);    for(i=0;i<len;i++){    //注意思考下面简单的分类讨论;         if(a[i]>='a'&&a[i]<='z') num1[a[i]-'a']++;//这种转换方式很巧妙,学着点;         else if(a[i]>='A'&&a[i]<='Z'&&num1[a[i]-'A']>0) num1[a[i]-'A']--;        else if(a[i]>='A'&&a[i]<='Z'&&num1[a[i]-'A']==0)  ans++;    }    printf("%d\n",ans);}

B. Pasha and String
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Pasha got a very beautiful string s for his birthday, the string consists of lowercase Latin letters. The letters in the string are numbered from 1 to |s| from left to right, where |s| is the length of the given string.

Pasha didn't like his present very much so he decided to change it. After his birthday Pasha spent m days performing the following transformations on his string — each day he chose integer ai and reversed a piece of string (a segment) from position ai to position|s| - ai + 1. It is guaranteed that ai ≤ |s|.

You face the following task: determine what Pasha's string will look like after m days.

Input

The first line of the input contains Pasha's string s of length from 2 to 2·105 characters, consisting of lowercase Latin letters.

The second line contains a single integer m (1 ≤ m ≤ 105) —  the number of days when Pasha changed his string.

The third line contains m space-separated elements ai (1 ≤ aiai ≤ |s|) — the position from which Pasha started transforming the string on the i-th day.

Output

In the first line of the output print what Pasha's string s will look like after m days.

Sample test(s)
input
abcdef12
output
aedcbf
input
vwxyz22 2
output
vwxyz
input
abcdef31 2 3
output
fbdcea

这道题目的大致意思是:

有一个字符串s,从左往右标记为1~n,然后第二行读入一个数m,相当于有m次询问,然后对于每一次询问,要你改变 ai 与 s-ai+1 这两个位置的字符(注意是从ai 开始改变,直到两个位置碰到为止)。

暴力没想法的结果就是果断的TLE。

实际上,这道题,先把每个位置的字符需要改变的次数求出来保存在一个数组中,然后若次数是奇数,才需要进行交换操作,否则则不用(仔细想想,应该很容易想通)。

但是这里只要储存每个起始位置的次数就好了(注意这里不要去存后面那个结束位置,要不然就相当于前面换了一次,后面也换了一次,那么不就相当于没换吗),因为其他的话是可以进行累加上去的。

#include<stdio.h>#include<string.h>char a[222222];int sum[222222]={0};int len;//n代表的是开始起始改变的位置,t代表的是改变位置的终点; void change(int n,int t){char c;int i,j;c=a[n]; a[n]=a[t]; a[t]=c;}int main(){int m,n,i,j,k;int t;scanf("%s",a);len=strlen(a);scanf("%d",&m);while(m--){scanf("%d",&n);//这里很重要,因为题目是从1开始标记的; n=n-1;sum[n]++;}if(sum[0]%2) change(0,len-1);//这里只要进行到len/2就可以了 for(i=1;i<len/2;i++){//如果要算出第i个位置需要交换的次数的话,那么这样累加就可以了; sum[i]+=sum[i-1];if(sum[i]%2) change(i,len-1-i);}printf("%s\n",a);}

C. Ilya and Sticks
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

In the evening, after the contest Ilya was bored, and he really felt like maximizing. He remembered that he had a set of n sticks and an instrument. Each stick is characterized by its length li.

Ilya decided to make a rectangle from the sticks. And due to his whim, he decided to make rectangles in such a way that maximizes their total area. Each stick is used in making at most one rectangle, it is possible that some of sticks remain unused. Bending sticks is not allowed.

Sticks with lengths a1a2a3 and a4 can make a rectangle if the following properties are observed:

  • a1 ≤ a2 ≤ a3 ≤ a4
  • a1 = a2
  • a3 = a4

A rectangle can be made of sticks with lengths of, for example, 3 3 3 3 or 2 2 4 4. A rectangle cannot be made of, for example, sticks5 5 5 7.

Ilya also has an instrument which can reduce the length of the sticks. The sticks are made of a special material, so the length of each stick can be reduced by at most one. For example, a stick with length 5 can either stay at this length or be transformed into a stick of length 4.

You have to answer the question — what maximum total area of the rectangles can Ilya get with a file if makes rectangles from the available sticks?

Input

The first line of the input contains a positive integer n (1 ≤ n ≤ 105) — the number of the available sticks.

The second line of the input contains n positive integers li (2 ≤ li ≤ 106) — the lengths of the sticks.

Output

The first line of the output must contain a single non-negative integer — the maximum total area of the rectangles that Ilya can make from the available sticks.

Sample test(s)
input
42 4 4 2
output
8
input
42 2 3 5
output
0
input
4100003 100004 100005 100006
output
10000800015

  • a1 ≤ a2 ≤ a3 ≤ a4
  • a1 = a2
  • a3 = a4
在满足以上条件的情况下,然后叫你求在所给的那么多根棍子中,能组成所有面积总和的最大值。并且他还有一个特殊功能,那就是能把一根棍子砍掉一个长度,但是这个操作只有一次。一开始看错题目,以为是只要求4根棍子然后组成一个面积的最大值,没想倒是所有的,读题还是不仔细啊。

思路:

开一个数组cnt[ ],存每一种长度的木棍的数量。然后同时找出最大值和最小值。

1.如果cnt[len]是奇数,并且cnt[len-1]>0 . 那么我们可以令 cnt[len]- -; 并且 cnt[len-1]++; 因为后面的那个长度变到了前面的那个长度。

2.如果cnt[len]是奇数,但是cnt[len-1]的木棍数量为0,那么我们就令cnt[len]- -; 但是 cnt[len-1]不用加1.

这样子之后,我们就保证了所有长度的数量都是偶数。

然后我们就从大的长度for一遍到小的长度。然后每四个就进行一次求面积。

注意要开__int64,要不然样例三就有会存不下。

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;__int64 cnt[1111111]={0};int len;int main(){int n,i,j,k=0;int max1=-1,min1=99999999;//printf("%d %d\n",max1,min1);scanf("%d",&n);for(i=1;i<=n;i++){scanf("%d",&len);if(max1<len) max1=len;if(min1>len) min1=len;  //printf("%d %d\n",max1,min1);cnt[len]++;}//printf("%d\n",cnt[len]);for(i=max1;i>min1;i--){if(cnt[i]%2 && cnt[i-1]){cnt[i]--;  cnt[i-1]++;}  else if(cnt[i]%2 && cnt[i-1]==0){cnt[i]--;}}__int64 area=0,t[5]={0};for(i=max1;i>=min1;i--){if(cnt[i]==0) continue;else{//printf("%d\n",i);//j代表的是i长度的木棍的数量; for(j=1;j<=cnt[i];j++){t[k++]=i;if(k==4) {area+=t[0]*t[3];  memset(t,0,sizeof(t));  k=0; continue;}}}}printf("%I64d\n",area);}





0 0
原创粉丝点击