浙江省赛部分题解

Sequence in the Pocket

DreamGrid has just found an integer sequence  in his right pocket. As DreamGrid is bored, he decides to play with the sequence. He can perform the following operation any number of times (including zero time): select an element and move it to the beginning of the sequence.

What's the minimum number of operations needed to make the sequence non-decreasing?

Input

There are multiple test cases. The first line of the input contains an integer , indicating the number of test cases. For each test case:

The first line contains an integer  (), indicating the length of the sequence.

The second line contains  integers  (), indicating the given sequence.

It's guaranteed that the sum of  of all test cases will not exceed .

Output

For each test case output one line containing one integer, indicating the answer.

Sample Input

2
4
1 3 2 4
5
2 3 3 5 5

Sample Output

2
0

Hint

For the first sample test case, move the 3rd element to the front (so the sequence become {2, 1, 3, 4}), then move the 2nd element to the front (so the sequence become {1, 2, 3, 4}). Now the sequence is non-decreasing.

For the second sample test case, as the sequence is already sorted, no operation is needed.

题意:可以把每个点放到队列的最前面,问最少用多少次操作可以把这个序列变成非递减序列?

给出的是无序序列,我们把这个队列排一次序,因为如果有点在这个排过序的序列中的相对顺序和原序列一样,就说明这些点是不用换的,这样就可以求出有多少个点需要操作了......awsl

#include
using namespace std;
const int N=1e5+10;
int a[N],n,b[N];
int main()
{
    int t;
    while(~scanf("%d",&t)){
        while(t--){
            scanf("%d",&n);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
                b[i]=a[i];
            }
            sort(a+1,a+1+n);
            int j=n;
            for(int i=n;i>=1;i--){
                if(a[j]==b[i])
                    j--;
            }
            printf("%d\n",j);
        }
    }
}

Singing Everywhere

Baobao loves singing very much and he really enjoys a game called Singing Everywhere, which allows players to sing and scores the players according to their performance.

Consider the song performed by Baobao as an integer sequence , where  indicates the -th note in the song. We say a note  is a "voice crack" if ,  and . The more voice cracks BaoBao sings, the lower score he gets.

To get a higher score, BaoBao decides to delete at most one note in the song. What's the minimum number of times BaoBao sings a voice crack after this operation?

Input

There are multiple test cases. The first line of the input contains an integer  (about 100), indicating the number of test cases. For each test case:

The first line contains one integer  (), indicating the length of the song.

The second line contains  integers  (), indicating the song performed by BaoBao.

It's guaranteed that at most 5 test cases have .

Output

For each test case output one line containing one integer, indicating the answer.

Sample Input

3
6
1 1 4 5 1 4
7
1 9 1 9 8 1 0
10
2 1 4 7 4 8 3 6 4 7

Sample Output

1
0
2

Hint

For the first sample test case, BaoBao does not need to delete a note. Because if he deletes no note, he will sing 1 voice crack (the 4th note), and no matter which note he deletes, he will also always sing 1 voice crack.

For the second sample test case, BaoBao can delete the 3rd note, and no voice cracks will be performed. Yay!

For the third sample test case, BaoBao can delete the 4th note, so that only 2 voice cracks will be performed (4 8 3 and 3 6 4).

题意:问可以删除一个点,使这个序列中一个数比前面的数大并且比后面的数也大的数最少?

只有当相隔1的两个点都是这种点并且相等的时候才可以删除他俩间的那个点,使得一下减2,其余可以分别判断符合条件的点钟删除它或者他前面或它后面的点。

就是判断有点多,需要仔细,但还是一遍就写过了......

#include
using namespace std;
const int N=1e5+10;
int a[N],n;
bool vis[N];
int main()
{
    int t;
    while(~scanf("%d",&t)){
        while(t--){
                memset(a,0,sizeof(a));
                int ans=0;
            scanf("%d",&n);
            memset(vis,false,sizeof(vis));
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            for(int i=2;ia[i-1]&&a[i]>a[i+1])
                   ans++,vis[i]=1;
        bool flag=false;
        bool flag2=false;
            for(int i=2;ia[i-2]&&a[i]>a[i+1])&&vis[i])
                    flag2=true;
                else if(!(a[i]>a[i+2]&&a[i]>a[i-2])&&vis[i])
                    flag2=true;
                else {
                    if(vis[i]){
                        if(i==2){
                            if(!(a[i+1]>a[i-1]&&a[i+1]>a[i+2]))
                                flag2=true;
                        }
                        else if(i==n-1){
                            if(!(a[i-1]>a[i-2]&&a[i-1]>a[i+1]))
                                flag2=true;
                        }
                        else {
                            if(!(a[i+1]>a[i-1]&&a[i+1]>a[i+2])&&!(a[i-1]>a[i-2]&&a[i-1]>a[i+1]))
                                flag2=true;
                        }
                    }
                }
            }
            if(flag)
                continue;
            else if(flag2)
                printf("%d\n",ans-1);
            else printf("%d\n",ans);
        }
    }
}

Welcome Party

The 44th World Finals of the International Collegiate Programming Contest (ICPC 2020) will be held in Moscow, Russia. To celebrate this annual event for the best competitive programmers around the world, it is decided to host a welcome party for all  participants of the World Finals, numbered from  to  for convenience.

The party will be held in a large hall. For security reasons, all participants must present their badge to the staff and pass a security check in order to be admitted into the hall. Due to the lack of equipment to perform the security check, it is decided to open only one entrance to the hall, and therefore only one person can enter the hall at a time.

Some participants are friends with each other. There are  pairs of mutual friendship relations. Needless to say, parties are more fun with friends. When a participant enters the hall, if he or she finds that none of his or her friends is in the hall, then that participant will be unhappy, even if his or her friends will be in the hall later. So, one big problem for the organizer is the order according to which participants enter the hall, as this will determine the number of unhappy participants. You are asked to find an order that minimizes the number of unhappy participants. Because participants with smaller numbers are more important (for example the ICPC director may get the number 1), if there are multiple such orders, you need to find the lexicographically smallest one, so that important participants enter the hall first.

Please note that if participant  and  are friends, and if participant  and  are friends, it's NOT necessary that participant  and  are friends.

Input

There are multiple test cases. The first line of the input contains a positive integer , indicating the number of cases. For each test case:

The first line contains two integers  and  (), the number of participants and the number of friendship relations.

The following  lines each contains two integers  and  (), indicating that the -th and the -th participant are friends. Each friendship pair is only described once in the input.

It is guaranteed that neither the sum of  nor the sum of  of all cases will exceed .

Output

For each case, print a single integer on the first line, indicating the minimum number of unhappy participants. On the second line, print a permutation of  to  separated by a space, indicating the lexicographically smallest ordering of participants entering the hall that achieves this minimum number.

Consider two orderings  and , we say  is lexicographically smaller than , if there exists an integer  (), such that  holds for all , and .

Please, DO NOT output extra spaces at the end of each line, or your solution may be considered incorrect!

Sample Input

2
4 3
1 2
1 3
1 4
4 2
1 2
3 4

Sample Output

1
1 2 3 4
2
1 2 3 4

 

这个题当时察觉到用BFS了,但当时脑子可能转不动了,,第二天写了第二发就过了......

因为要使不高兴的最少,但肯定会有不高兴的,所以用并查集找联通块,并且处理的时候要让小的点当父节点,然后把根节点放入优先队列中,在进行BFS再把与队首的点相连的点也加进优先队列中,一直这样操作就好......

#include
using namespace std;
const int N=1e6+10;
vectorv[N];
int pre[N],n,m;
bool vis[N];
priority_queue,greater >q;
int Find(int x)
{
   return pre[x]==x?x:Find(pre[x]);
}
void join(int x,int y)
{
    int fx=Find(x);
    int fy=Find(y);
    if(fx!=fy){
        if(fx

 

你可能感兴趣的:(训练)