A. Detective Book
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Ivan recently bought a detective book. The book is so interesting that each page of this book introduces some sort of a mystery, which will be explained later. The i-th page contains some mystery that will be explained on page ai (iai≥i).
Ivan wants to read the whole book. Each day, he reads the first page he didn't read earlier, and continues to read the following pages one by one, until all the mysteries he read about are explained and clear to him (Ivan stops if there does not exist any page i such that Ivan already has read it, but hasn't read page ai). After that, he closes the book and continues to read it on the following day from the next page.
How many days will it take to read the whole book?
Input
The first line contains single integer n (1≤n≤104) — the number of pages in the book.
The second line contains nn integersa1,a2,…,an (i≤ai≤ni), where aiai is the number of page which contains the explanation of the mystery on page i.
Output
Print one integer — the number of days it will take to read the whole book.
Example
input
Copy
9
1 3 3 6 7 6 8 8 9
output
Copy
4
Note
Explanation of the example test:
During the first day Ivan will read only the first page. During the second day Ivan will read pages number 22 and 33. During the third day — pages 44-88. During the fourth (and the last) day Ivan will read remaining page number 99.
题意:
给你一本书,这本书有n页,然后接下来就是每一页的内容ai,这个数如果就是本来的编号,那么就是算十四解除谜题,如果不是,那么证明在这一页我们就有了一个谜题,如,1,3,3,按顺序他的标号为:1->1,2->3,3->3,在第一页,我们就解除了一的谜题,看第二页是,发现他的答案在第三页,那么先记下来,然后再看第三页,发现其答案就在这一页,那么结束了,最后,当在看书时,看到某一页已经没有了谜题,那么这一天就不看书了,如上述的那个就看了两天,第一天看第一页,第二天看了二、三页,看完了。问你总共花了多少天。
题解:
一开始觉得如果这一页的页数和这一夜的答案是一样的那不就是一天了吗,然后就的发现不对,他还有一个要求,一天的定义是在这一天我们已经没有谜题了,那才是一天,那么我觉得有点像集合的感觉,就是有一个谜题就是方静去,当这个集合在后面发现相同的页数时,那么这个集合的相同谜题就解答了,就消除,最后,当没有了谜题,就是一天完了。
代码:
#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <set>
#define ll long long
using namespace std ;
int a[10005] ;
set<int> s ;
int main()
{
int n ;
scanf("%d" , &n) ;
for(int i = 1 ; i <= n ; i ++) scanf("%d" , &a[i]) ;
int ans = 0 ;
s.clear() ;
for(int i = 1 ; i <= n ; i ++)
{
if(s.count(i)) s.erase(i) ;
if(a[i] != i) s.insert(a[i]) ;
else
{
if(s.count(i)) s.erase(i) ;
}
if(s.empty()) ans ++ ;
}
printf("%d\n" , ans) ;
return 0 ;
}
太菜了,居然两个小时就做了一题,自己昨天都不知道时怎么的。。。。。
补题:
B. Good String
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
You have a string ss of length nn consisting of only characters > and <. You may do some operations with this string, for each operation you have to choose some character that still remains in the string. If you choose a character >, the character that comes right after it is deleted (if the character you chose was the last one, nothing happens). If you choose a character <, the character that comes right before it is deleted (if the character you chose was the first one, nothing happens).
For example, if we choose character > in string > > < >, the string will become to > > >. And if we choose character < in string > <, the string will become to <.
The string is good if there is a sequence of operations such that after performing it only one character will remain in the string. For example, the strings >, > > are good.
Before applying the operations, you may remove any number of characters from the given string (possibly none, possibly up to n−1n−1, but not the whole string). You need to calculate the minimum number of characters to be deleted from string ss so that it becomes good.
Input
The first line contains one integer tt (1≤t≤1001≤t≤100) – the number of test cases. Each test case is represented by two lines.
The first line of ii-th test case contains one integer nn (1≤n≤1001≤n≤100) – the length of string ss.
The second line of ii-th test case contains string ss, consisting of only characters > and <.
Output
For each test case print one line.
For ii-th test case print the minimum number of characters to be deleted from string ss so that it becomes good.
Example
input
Copy
3
2
<>
3
><<
1
>
output
Copy
1
0
0
Note
In the first test case we can delete any character in string <>.
In the second test case we don't need to delete any characters. The string > < < is good, because we can perform the following sequence of operations: > < < →→ < < →→ <.
题意:
这个题当时看来半天没想法,就完了,去坐坐C吧,然后就CE两发C,WA了四发.....
算了还是将这个题吧,在看了题解后,将其过了,给你一个字符串,这个串只包含'<'和'>',那么可以又两种删除操作,就是选择'<'那么其前面的都可以进行自动删除,同理,选择'>'就是他后面的全部可以自动删除,但是有一些是不能自动删除的,那就是不包含在那两种操作里的,如样例中的"<>",这时侯定义可以进行人工删除,将其不能剪掉的进行人工删除后,就可以办成good串,着串就是可以进行自动删除的那种,并且自动删除到最后只剩一个字符了。
题解:
一开始就是这个将我打的什么都不知道了,看完题解,自己在想了一想,发现,当着穿不是good串的时侯,那么在这里面,应该是存在"<>"这种子串,那么我该人工删除多少呢?并且是最小的数量?那么"<>"当出现这种时,呢吗就是要么左边不能删到一个,要么就是右边不能删除到一个,对了,在这里时必须人工删除在自动删除之前的,那么我们找到'>'的第一个位置和'<'的最后一个位置,这么的话,'>'的前面就是要删除的,因为在'>'的第一个位置前面的都不能通过选择'>'删除掉,'<'的后面的都是要删除的,同理的,那么我们就可以去一个最小值就行了。
代码:
#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <queue>
#define ll long long
using namespace std ;
int main()
{
int T ;
scanf("%d" , &T) ;
while(T --)
{
int n ;
scanf("%d" , &n) ;
string s ;
cin >> s ;
int tmp = 0 , tmp1 = 0 , ans = 0 ;
for(int i = 0 ; i < n ; i ++)
{
if(s[i] == '>')
{
tmp = i ;
break ;
}
}
for(int i = n - 1 ; i >= 0 ; i --)
{
if(s[i] == '<')
{
tmp1 = i ;
break ;
}
}
ans = min(tmp , n - tmp1 - 1) ;
printf("%d\n" , ans) ;
}
return 0 ;
}
C. Playlist
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You have a playlist consisting of nn songs. The ii-th song is characterized by two numbers titi and bibi — its length and beauty respectively. The pleasure of listening to set of songs is equal to the total length of the songs in the set multiplied by the minimum beauty among them. For example, the pleasure of listening to a set of 33 songs having lengths [5,7,4][5,7,4] and beauty values [11,14,6][11,14,6] is equal to (5+7+4)⋅6=96(5+7+4)⋅6=96.
You need to choose at most kk songs from your playlist, so the pleasure of listening to the set of these songs them is maximum possible.
Input
The first line contains two integers nn and kk (1≤k≤n≤3⋅1051≤k≤n≤3⋅105) – the number of songs in the playlist and the maximum number of songs you can choose, respectively.
Each of the next nn lines contains two integers titi and bibi (1≤ti,bi≤1061≤ti,bi≤106) — the length and beauty of ii-th song.
Output
Print one integer — the maximum pleasure you can get.
Examples
input
Copy
4 3
4 7
15 1
3 6
6 8
output
Copy
78
input
Copy
5 3
12 31
112 4
100 100
13 55
55 50
output
Copy
10000
Note
In the first test case we can choose songs 1,3,41,3,4, so the total pleasure is (4+3+6)⋅6=78(4+3+6)⋅6=78.
In the second test case we can choose song 33. The total pleasure will be equal to 100⋅100=10000100⋅100=10000.
题意:
给你n首歌,你最多可以选择k首歌,但是这里有一个要求就是你选择后得到的pleasure要最大,这个值的计算是将你选的歌的时长全加起来,然后将其乘以这几首歌的最小beauty值,这时,你就要维护这个n首歌中你找的至多k首歌,并且你找到的要有最大值,这时候就需要优先队列了,因为你不知道你需要的值在哪里,你又不能想当然的取某某几首歌,那是不准确的,那就进行取舍吧,进行小根堆排序,把当前小的时长不断弃掉,放进大的时长,再保存这里面的pleasure的最大值就行了。
题解:
按题意,用优先队列的小根堆形式进行维护,不断进行更新,将最有利的值保存下来就可以了,当然,在开始你可以对美丽值进行歌曲排序,应为你总想取大的美丽值啊。
代码:
#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <queue>
#define ll long long
using namespace std ;
struct node
{
ll len , bea ;
bool operator < (const node &a) const {return a.bea < bea ;}
}no[300005] ;
priority_queue<int , vector<int> , greater<int> > q ;
int main()
{
int n , k ;
scanf("%d%d" , &n , &k) ;
for(int i = 1 ; i <= n ; i ++) scanf("%I64d%I64d" , &no[i].len , &no[i].bea) ;
sort(no + 1 , no + 1 + n) ;
ll minn = 1e9 , maxx = 0 , sum = 0 ;
for(int i = 1 ; i <= n ; i ++)
{
sum += no[i].len ;
q.push(no[i].len) ;
if(q.size() > k) sum -= q.top() , q.pop() ;
maxx = max(maxx , sum * no[i].bea) ;
}
printf("%I64d\n" , maxx) ;
return 0 ;
}
D. Minimum Triangulation
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You are given a regular polygon with nn vertices labeled from 11 to nn in counter-clockwise order. The triangulation of a given polygon is a set of triangles such that each vertex of each triangle is a vertex of the initial polygon, there is no pair of triangles such that their intersection has non-zero area, and the total area of all triangles is equal to the area of the given polygon. The weight of a triangulation is the sum of weigths of triangles it consists of, where the weight of a triagle is denoted as the product of labels of its vertices.
Calculate the minimum weight among all triangulations of the polygon.
Input
The first line contains single integer nn (3≤n≤5003≤n≤500) — the number of vertices in the regular polygon.
Output
Print one integer — the minimum weight among all triangulations of the given polygon.
Examples
input
Copy
3
output
Copy
6
input
Copy
4
output
Copy
18
Note
According to Wiki: polygon triangulation is the decomposition of a polygonal area (simple polygon) PP into a set of triangles, i. e., finding a set of triangles with pairwise non-intersecting interiors whose union is PP.
In the first example the polygon is a triangle, so we don't need to cut it further, so the answer is 1⋅2⋅3=61⋅2⋅3=6.
In the second example the polygon is a rectangle, so it should be divided into two triangles. It's optimal to cut it using diagonal 1−31−3 so answer is 1⋅2⋅3+1⋅3⋅4=6+12=181⋅2⋅3+1⋅3⋅4=6+12=18.
题意:
这题我在打的时候,看了,还以为是求组成的三角个数,其实差不多吧(差太多了吧....)就是给你一个n,就是一个正n边形 ,然后顶点会按1到n编号,在这个n边形中连接上不相交的边,这些边会组成三角形,没有三角形是面积为零,然后定义了一个三角形重量的概念,就是在这个三角形中,会将三个点的乘积作为这个三角形的重量,最后问你最小的重量,总的重量是每个三角形的重量和。
题解:
既然是最小,那么将1作为所有三件形的连接点,那就会减少重量了,然后,你画画图就会发现,原来如此的简单?对没错就是这样的,可惜我没做......
代码:
#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <queue>
#define ll long long
using namespace std ;
int main()
{
int n ;
scanf("%d" , &n) ;
ll ans = 0 ;
while(n >= 3) ans += 1ll * n * (n - 1) , n --;
printf("%I64d\n" , ans) ;
return 0 ;
}
菜得不一样,菜出新高度。