SDNU_ACM_ICPC_2019_Winter_Practice_4th 题解

A - Frog Jumping

A frog is currently at the point 00 on a coordinate axis OxOx. It jumps by the following algorithm: the first jump is aa units to the right, the second jump is bbunits to the left, the third jump is aa units to the right, the fourth jump is bbunits to the left, and so on.

Formally:

  • if the frog has jumped an even number of times (before the current jump), it jumps from its current position xx to position x+ax+a;
  • otherwise it jumps from its current position xx to position x−bx−b.

Your task is to calculate the position of the frog after kk jumps.

But... One more thing. You are watching tt different frogs so you have to answer ttindependent queries.

Input

The first line of the input contains one integer tt (1≤t≤10001≤t≤1000) — the number of queries.

Each of the next tt lines contain queries (one query per line).

The query is described as three space-separated integers a,b,ka,b,k (1≤a,b,k≤1091≤a,b,k≤109) — the lengths of two types of jumps and the number of jumps, respectively.

Output

Print tt integers. The ii-th integer should be the answer for the ii-th query.

代码:

#include
using namespace std;
#define maxn 110
#define up(i,x,y) for(int i=x;i<=y;i++)
#define down(i,x,y) for(int i=x;i>=y;i--)
typedef long long ll;
int main()
{
    int t;cin>>t;
    while(t--)
    {
        int a,b,k;scanf("%d %d %d",&a,&b,&k);
        ll ans=0;
        if(k%2==0)cout<<1LL*(a-b)*k/2<

题解:最初在坐标的0位置,先向右a个单位,再向左b个单位,共持续k个回合。

数学题目,分奇偶讨论一下就可以了,注意不要爆int.

B - Disturbed People

There is a house with nn flats situated on the main street of Berlatov. Vova is watching this house every night. The house can be represented as an array of nninteger numbers a1,a2,…,ana1,a2,…,an, where ai=1ai=1 if in the ii-th flat the light is on and ai=0ai=0 otherwise.

Vova thinks that people in the ii-th flats are disturbed and cannot sleep if and only if 1

Vova is concerned by the following question: what is the minimum number kk such that if people from exactly kk pairwise distinct flats will turn off the lights then nobody will be disturbed? Your task is to find this number kk.

Input

The first line of the input contains one integer nn (3≤n≤1003≤n≤100) — the number of flats in the house.

The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (ai∈{0,1}ai∈{0,1}), where aiaiis the state of light in the ii-th flat.

Output

Print only one integer — the minimum number kk such that if people from exactly kkpairwise distinct flats will turn off the light then nobody will be disturbed.

代码:

#include
using namespace std;
#define maxn 110
#define up(i,x,y) for(int i=x;i<=y;i++)
#define down(i,x,y) for(int i=x;i>=y;i--)
typedef long long ll;
int a[maxn];
int main()
{
    int n;cin>>n;
    up(i,1,n)cin>>a[i];
    int res=0;
    up(i,2,n-1)
    {
        if(a[i]==0&&a[i-1]==1&&a[i+1]==1)
        {
            res++;a[i+1]=0;
        }
    }
    cout<

题解:输入一个n,再输入n个数代表房子灯的亮灭。如果此时a[i]==0&&a[i-1]==1&&a[i+1]==1代表被打扰,res就要++;

贪心,如果此时这个房子的人被打扰了,那么为了消除影响,应该使下一个将要访问的房子置0,因为这样才能使ans尽量小。

C - Good Array

Let's call an array good if there is an element in the array that equals to the sum of all other elements. For example, the array a=[1,3,3,7]a=[1,3,3,7] is good because there is the element a4=7a4=7 which equals to the sum 1+3+31+3+3.

You are given an array aa consisting of nn integers. Your task is to print all indices jj of this array such that after removing the jj-th element from the array it will be good (let's call such indices nice).

For example, if a=[8,3,5,2]a=[8,3,5,2], the nice indices are 11 and 44:

  • if you remove a1a1, the array will look like [3,5,2][3,5,2] and it is good;
  • if you remove a4a4, the array will look like [8,3,5][8,3,5] and it is good.

You have to consider all removals independently, i. e. remove the element, check if the resulting array is good, and return the element into the array.

Input

The first line of the input contains one integer nn (2≤n≤2⋅1052≤n≤2⋅105) — the number of elements in the array aa.

The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1061≤ai≤106) — elements of the array aa.

Output

In the first line print one integer kk — the number of indices jj of the array aa such that after removing the jj-th element from the array it will be good (i.e. print the number of the nice indices).

In the second line print kk distinct integers j1,j2,…,jkj1,j2,…,jk in any order — niceindices of the array aa.

If there are no such indices in the array aa, just print 00 in the first line and leave the second line empty or do not print it at all.

代码:

#include
using namespace std;
#define maxn (int)5e5+1000
#define up(i,x,y) for(int i=x;i<=y;i++)
#define down(i,x,y) for(int i=x;i>=y;i--)
typedef long long ll;
struct p
{
    int v,id;
}P[maxn];
vectorres;
bool cmp(p a,p b)
{
    return a.v>n;
    up(i,1,n)cin>>P[i].v,P[i].id=i;
    sort(P+1,P+n+1,cmp);
    ll sum=0;
    up(i,1,n-1)sum+=P[i].v;
    up(i,1,n-1)
    {
        if(sum-P[i].v==P[n].v)res.push_back(P[i].id);
    }
    if(sum-P[n-1].v==P[n-1].v)res.push_back(P[n].id);
    cout<0)
    {
        up(i,0,res.size()-1)
        printf("%d%c",res[i],i==res.size()-1?'\n':' ');
    }
    else cout<

题解: 输入一个数n和一个大小为n的数组,要删除一个数,然后其它的n-2数相加等于没用到的那个数。

因为a[i]>0 1<=i<=n  所以删去一个数后,一定是最大那个数等于另外的数之和。

先拍一下序,然后暴力,看删去这个数之后,看是否符合较小的那些数的和等于最大那个数,用结构体记录ID的编号。

最后输出。

D - Cutting Out

You are given an array ss consisting of nn integers.

You have to find any array tt of length kk such that you can cut out maximum number of copies of array tt from array ss.

Cutting out the copy of tt means that for each element titi of array tt you have to find titi in ss and remove it from ss. If for some titi you cannot find such element in ss, then you cannot cut out one more copy of tt. The both arrays can contain duplicate elements.

For example, if s=[1,2,3,2,4,3,1]s=[1,2,3,2,4,3,1] and k=3k=3 then one of the possible answers is t=[1,2,3]t=[1,2,3]. This array tt can be cut out 22 times.

  • To cut out the first copy of tt you can use the elements [1,2−−,3,2,4,3−−,1−−][1,2_,3,2,4,3_,1_] (use the highlighted elements). After cutting out the first copy of tt the array ss can look like [1,3,2,4][1,3,2,4].
  • To cut out the second copy of tt you can use the elements [1−−,3−−,2−−,4][1_,3_,2_,4]. After cutting out the second copy of tt the array ss will be [4][4].

Your task is to find such array tt that you can cut out the copy of tt from ss maximum number of times. If there are multiple answers, you may choose any of them.

Input

The first line of the input contains two integers nn and kk (1≤k≤n≤2⋅1051≤k≤n≤2⋅105) — the number of elements in ss and the desired number of elements in tt, respectively.

The second line of the input contains exactly nn integers s1,s2,…,sns1,s2,…,sn (1≤si≤2⋅1051≤si≤2⋅105).

Output

Print kk integers — the elements of array tt such that you can cut out maximum possible number of copies of this array from ss. If there are multiple answers, print any of them. The required array tt can contain duplicate elements. All the elements of tt (t1,t2,…,tkt1,t2,…,tk) should satisfy the following condition: 1≤ti≤2⋅1051≤ti≤2⋅105

代码

#include
using namespace std;
#define maxn 110
#define up(i,x,y) for(int i=x;i<=y;i++)
#define down(i,x,y) for(int i=x;i>=y;i--)
typedef long long ll;
mapT;
int n,k;
bool C(int x)
{
    int res=0;
    for(map::iterator it=T.begin();it!=T.end();it++)
    {
        res+=((*it).second/x);
        if(res>=k)return 1;
    }
    return 0;
}
vectorV;
int main()
{
    cin>>n>>k;
    int lo=1,hi=(int)1e9;
    up(i,1,n)
    {
        int x;scanf("%d",&x);
        T[x]++;
        //hi=max(hi,T[x]);
    }
    int res;
    while(lo<=hi)
    {
        int mid=(lo+hi)/2;
        if(C(mid))lo=mid+1,res=mid;
        else hi=mid-1;
    }
    for(map::iterator it=T.begin();it!=T.end();it++)
    {
        int tmp=(*it).second/res;
        while(tmp--)
        {
            V.push_back((*it).first);
        }
    }
    up(i,1,k)
    printf("%d%c",V[i-1],i==k?'\n':' ');
}

题解:二分题    读题好晕

输入一个n和k,然后输入一个n的大小的数组。  要最大化切的次数,并且每次切必须k个数,这k个数可以重复。每次切都要切相同的k个数。

先最大化切的次数,最后根据次数找出要切的k个数。

可以用map存每个数出现的次数。

对于每个枚举的x次切割,看是否有k个数。

因为可以有重复出现的数,,所以用map中存的次数/要切割的次数,就是可以在这K个数中占据的个数,最后个数相加,如果大于K就代表此次切割次数成立。

最后根据最大切割次数往回找那k个数。。。

E - Thematic Contests

 

Polycarp has prepared nn competitive programming problems. The topic of the ii-th problem is aiai, and some problems' topics may coincide.

Polycarp has to host several thematic contests. All problems in each contest should have the same topic, and all contests should have pairwise distinct topics. He may not use all the problems. It is possible that there are no contests for some topics.

Polycarp wants to host competitions on consecutive days, one contest per day. Polycarp wants to host a set of contests in such a way that:

  • number of problems in each contest is exactly twice as much as in the previous contest (one day ago), the first contest can contain arbitrary number of problems;
  • the total number of problems in all the contests should be maximized.

Your task is to calculate the maximum number of problems in the set of thematic contests. Note, that you should not maximize the number of contests.

Input

The first line of the input contains one integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the number of problems Polycarp has prepared.

The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109) where aiaiis the topic of the ii-th problem.

Output

Print one integer — the maximum number of problems in the set of thematic contests.

#include
using namespace std;
#define maxn 110
#define up(i,x,y) for(int i=x;i<=y;i++)
#define down(i,x,y) for(int i=x;i>=y;i--)
typedef long long ll;
mapT;
vectorV;
int main()
{
    int n;cin>>n;
    up(i,1,n)
    {
        int x;scanf("%d",&x);
        T[x]+=1;
    }
    for(map::iterator it=T.begin();it!=T.end();it++)
    {
        V.push_back((*it).second);
    }
    sort(V.begin(),V.end());
    //up(i,0,V.size()-1)cout<

题解:老套路 输入一个数N,再输入一个大小为N的数组。

每一个主题都有自己的题目数,又可以用map存起来。

因为题目的主题序号对题目没有影响,所以光把次数push_back进vector,此时找到出现最多的次数maxxx

然后二分暴力找,先枚举第一次出现的题目数 i  (1,maxxx),

再枚举每场比赛的题目数 j,在每场比赛中贪心找第一个大于等于j的主题。

接下来的比赛一定在这个主题之后(主题的题目数已拍过序);

最后输出最多的题目数。

F - Almost Regular Bracket Sequence

You are given a bracket sequence ss consisting of nn opening '(' and closing ')' brackets.

A regular bracket sequence is a bracket sequence that can be transformed into a correct arithmetic expression by inserting characters '1' and '+' between the original characters of the sequence. For example, bracket sequences "()()", "(())" are regular (the resulting expressions are: "(1)+(1)", "((1+1)+1)"), and ")(" and "(" are not.

You can change the type of some bracket sisi. It means that if si=si= ')' then you can change it to '(' and vice versa.

Your task is to calculate the number of positions ii such that if you change the type of the ii-th bracket, then the resulting bracket sequence becomes regular.

Input

The first line of the input contains one integer nn (1≤n≤1061≤n≤106) — the length of the bracket sequence.

The second line of the input contains the string ss consisting of nn opening '(' and closing ')' brackets.

Output

Print one integer — the number of positions ii such that if you change the type of the ii-th bracket, then the resulting bracket sequence becomes regular.

代码

#include
using namespace std;
#define maxn (int)1e6+1000
#define up(i,x,y) for(int i=x;i<=y;i++)
#define down(i,x,y) for(int i=x;i>=y;i--)
typedef long long ll;
int lx[maxn],rx[maxn];
int main()
{
    int n;cin>>n;
    string sh;cin>>sh;
    up(i,0,n-1)
    {
        if(i!=0)
        {
            lx[i]=lx[i-1];rx[i]=rx[i-1];
        }
        if(sh[i]=='(')lx[i]++;
        else rx[i]++;
    }
    if(lx[n-1]-rx[n-1]==2)
    {
        int ans=0;
        up(i,0,n-1)if(lx[i]-rx[i]<0){cout<<0<=2)
            {
                if(sh[i]=='(')ans++;
            }
            else break;
        }
        cout<=0)
            {
                if(sh[i]==')')ans++;
            }
            else break;
        }
        cout<

题解:输入包括(,)的字符串。问可以翻转 把‘(’变成‘)’ 

之后得到规则的串。问这样成立的位置个数。

如果单给你一个串问你是否规则。用lx[i]记录前缀左括号的个数,rx[i]记录右括号的个数。

那么一定符合 lx[i]-rx[i]>=0 (1<=i<=n-1 )&& lx[n]-rx[n]==0   

现在因为要翻转一次,所以一定有 abs(lx[n]-rx[n])==2  要不就输出0

如果左括号多(现在寻找可以将左括号的换成右括号的位置):

换过之后(一个)  lx[n]-rx[n]==0  必定成立   (lx[n]--,rx[n]++,当然成立了)

所以要保证前一个条件成立 :即 lx[i]-rx[i]>=0 (1<=i<=n-1 )

翻转之后的后果是使当前位置和以后位置的lx[i]-rx[i]的差-2;

首先保证 所有位置的 lx[i]-rx[i]>=0;然后再从后往前找,找此时位置lx[i]-rx[i]>=2左括号数目,

如果不成立就break,因为前面和此时的括号改变会使lx[i]-rx[i]-2<0;

找右括号也一样,它的翻转会使后面的差值+2;

一定要符合两个结论,然后用逻辑模拟一下就好了。

G - Circular Dance

There are nn kids, numbered from 11 to nn, dancing in a circle around the Christmas tree. Let's enumerate them in a clockwise direction as p1p1, p2p2, ..., pnpn (all these numbers are from 11 to nn and are distinct, so pp is a permutation). Let the next kid for a kid pipi be kid pi+1pi+1 if i

 Example: 5 kids in a circle, p=[3,2,4,1,5]p=[3,2,4,1,5] (or any cyclic shift). The information kids remembered is: a1,1=3a1,1=3, a1,2=5a1,2=5; a2,1=1a2,1=1, a2,2=4a2,2=4; a3,1=2a3,1=2, a3,2=4a3,2=4; a4,1=1a4,1=1, a4,2=5a4,2=5; a5,1=2a5,1=2, a5,2=3a5,2=3.

You have to restore the order of the kids in the circle using this information. If there are several answers, you may print any. It is guaranteed that at least one solution exists.

If you are Python programmer, consider using PyPy instead of Python when you submit your code.

Input

The first line of the input contains one integer nn (3≤n≤2⋅1053≤n≤2⋅105) — the number of the kids.

The next nn lines contain 22 integers each. The ii-th line contains two integers ai,1ai,1and ai,2ai,2 (1≤ai,1,ai,2≤n,ai,1≠ai,21≤ai,1,ai,2≤n,ai,1≠ai,2) — the kids the ii-th kid remembered, given in arbitrary order.

Output

Print nn integers p1p1, p2p2, ..., pnpn — permutation of integers from 11 to nn, which corresponds to the order of kids in the circle. If there are several answers, you may print any (for example, it doesn't matter which kid is the first in the circle). It is guaranteed that at least one solution exists.

代码

#include
using namespace std;
#define maxn (int)3e5+1000
#define up(i,x,y) for(int i=x;i<=y;i++)
#define down(i,x,y) for(int i=x;i>=y;i--)
typedef long long ll;
int nxt1[maxn],nxt2[maxn];
vectorres;
int main()
{
    int n;cin>>n;
    up(i,1,n)scanf("%d %d",&nxt1[i],&nxt2[i]);
    res.push_back(1);
    int f=1;
    while(res.size()0)
    {
        up(i,0,res.size()-1)
        printf("%d%c",res[i],i==res.size()-1?'\n':' ');
    }
}

题意: n个小孩围成一个圈,每个小孩都好自己的序号,他会说出自己的后两个人的序号。

首先自己选定一个序号,设x,假设它的后两个小孩是x1,x2。

要给x1,x2排序 是   x , x1, x2 还是   x ,x2,x1  ;

如果是第一种情况    那么x1说出的后两个孩子中一定有x2;   同理

注意n为偶数的情况,此时最后一次只排一个人。。

H - Powers Of Two

 

A positive integer xx is called a power of two if it can be represented as x=2yx=2y, where yy is a non-negative integer. So, the powers of two are 1,2,4,8,16,…1,2,4,8,16,….

You are given two positive integers nn and kk. Your task is to represent nn as the sumof exactly kk powers of two.

Input

The only line of the input contains two integers nn and kk (1≤n≤1091≤n≤109, 1≤k≤2⋅1051≤k≤2⋅105).

Output

If it is impossible to represent nn as the sum of kk powers of two, print NO.

Otherwise, print YES, and then print kk positive integers b1,b2,…,bkb1,b2,…,bk such that each of bibi is a power of two, and ∑i=1kbi=n∑i=1kbi=n. If there are multiple answers, you may print any of them.

代码

#include
using namespace std;
#define maxn 110
#define up(i,x,y) for(int i=x;i<=y;i++)
#define down(i,x,y) for(int i=x;i>=y;i--)
typedef long long ll;
int a[32];
vectorres;
int main()
{
    int n,k;cin>>n>>k;
    int cnt=0;
    up(i,0,30)
    {
        if( (n&(1< 0)
            cnt++,a[i]++;
    }
    //up(i,0,30)cout<n){puts("NO");return 0;}
    else
    {
        puts("YES");
        k-=cnt;
        down(i,30,1)
        {
            if(a[i]>0)
            {
                int tmp=min(k,a[i]);
                a[i-1]+= 2*tmp;
                a[i]-= tmp;
                k-=tmp;
            }
        }
    }
    up(i,0,30)
    {
        while(a[i]--)
            res.push_back((1<0)
    {
        up(i,0,res.size()-1)
        printf("%d%c",res[i],i==res.size()-1?'\n':' ');
    }
}

题解; 模拟二进制  k必须大于等于n用二进制表示的位数 ,

小于n

每次退位 会增加一个数  。模拟一下

I - Array Stabilization

You are given an array aa consisting of nn integer numbers.

Let instability of the array be the following value: maxi=1nai−mini=1naimaxi=1nai−mini=1nai.

You have to remove exactly one element from this array to minimize instability of the resulting (n−1)(n−1)-elements array. Your task is to calculate the minimum possible instability.

Input

The first line of the input contains one integer nn (2≤n≤1052≤n≤105) — the number of elements in the array aa.

The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1051≤ai≤105) — elements of the array aa.

Output

Print one integer — the minimum possible instability of the array if you have to remove exactly one element from the array aa.

代码:

include
using namespace std;
#define maxn (int)1e5+1000
#define up(i,x,y) for(int i=x;i<=y;i++)
#define down(i,x,y) for(int i=x;i>=y;i--)
typedef long long ll;
int a[maxn];
int main()
{
    int n;cin>>n;
    up(i,1,n)cin>>a[i];
    sort(a+1,a+n+1);
    cout<

题解:删除一个数 然后最大数-最小数  的最小值是多少。。

有点像凸包中的求两个点的距离最大。。 删最大的或者删最小的。。。

阔写完了。。。。。。。。

J - Repeating Cipher

 

Polycarp loves ciphers. He has invented his own cipher called repeating.

Repeating cipher is used for strings. To encrypt the string s=s1s2…sms=s1s2…sm (1≤m≤101≤m≤10), Polycarp uses the following algorithm:

  • he writes down s1s1 ones,
  • he writes down s2s2 twice,
  • he writes down s3s3 three times,
  • ...
  • he writes down smsm mm times.

For example, if ss="bab" the process is: "b" →→ "baa" →→ "baabbb". So the encrypted ss="bab" is "baabbb".

Given string tt — the result of encryption of some string ss. Your task is to decrypt it, i. e. find the string ss.

Input

The first line contains integer nn (1≤n≤551≤n≤55) — the length of the encrypted string. The second line of the input contains tt — the result of encryption of some string ss. It contains only lowercase Latin letters. The length of tt is exactly nn.

It is guaranteed that the answer to the test exists.

Output

Print such string ss that after encryption it equals tt.

代码

#include
using namespace std;
#define maxn 110
#define up(i,x,y) for(int i=x;i<=y;i++)
#define down(i,x,y) for(int i=x;i>=y;i--)
typedef long long ll;
int main()
{
    int n;cin>>n;
    string sh;cin>>sh;
    int cnt=0;
    for(int i=0;i

模拟   ~~~~~~~~~~~~~~~~~~~

如有不对或不好的地方,请加qq :1632039752 (打个广告。。

你可能感兴趣的:(SDNU_ACM_ICPC_2019_Winter_Practice_4th 题解)