2019/4/4日常CF练习Codeforces1140(A)补题(B,C,D)

本文是一篇关于Codeforces编程竞赛的解题心得分享,详细介绍了四道不同类型的题目:侦探书阅读、好字符串构造、最佳播放列表选择和最小三角剖分。通过分析题意、解题思路和代码实现,阐述了解决这些问题的关键策略和技巧。
摘要由CSDN通过智能技术生成

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 ;
}

菜得不一样,菜出新高度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值