fzuacm 2017 新生寒假训练 6

A - a

HDD hard drives group data by sectors. All files are split to fragments and each of them are written in some sector of hard drive. Note the fragments can be written in sectors in arbitrary order.

One of the problems of HDD hard drives is the following: the magnetic head should move from one sector to another to read some file.

Find the time need to read file split to n fragments. The i-th sector contains the*f i -th fragment of the file (1 ≤ *f i  ≤ n). Note different sectors contains the different fragments. At the start the magnetic head is in the position that contains the first fragment. The file are reading in the following manner: at first the first fragment is read, then the magnetic head moves to the sector that contains the second fragment, then the second fragment is read and so on until the n-th fragment is read. The fragments are read in the order from the first to the n-th.

It takes |a - b| time units to move the magnetic head from the sector a to the sector*b*. Reading a fragment takes no time.

Input:

The first line contains a positive integer n (1 ≤ n ≤ 2·10 5 ) — the number of fragments.

The second line contains n different integers f i (1 ≤  f i ≤ n) — the number of the fragment written in the i-th sector.

Output:

Print the only integer — the number of time units needed to read the file.

Example:

Input:

3
3 1 2

Output:

3

Input:

5
1 3 5 4 2

Output:

10

Note:

In the second example the head moves in the following way:

  • 1->2 means movement from the sector 1 to the sector 5, i.e. it takes 4 time units
  • 2->3 means movement from the sector 5 to the sector 2, i.e. it takes 3 time units
  • 3->4 means movement from the sector 2 to the sector 4, i.e. it takes 2 time units
  • 4->5 means movement from the sector 4 to the sector 3, i.e. it takes 1 time units

So the answer to the second example is 4 + 3 + 2 + 1 = 10.


Code:

#include <stdio.h>
#include <math.h>
int a[1000000];
int main (void)
{
    int n,t;
    long long sum = 0;
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&t);
        a[t]=i;
    }
    for (int i=2;i<=n;i++)
    {
        sum+=fabs(a[i]-a[i-1]);
    }
    printf("%I64d\n",sum);
    return 0;
}

// long long sum = 0;

// 所需时间最大值为1+2+ ··· + (2·10 5 - 1) = 2·10 1 0 (如样例2),已超过了 int 型所能表示的范围。

// a[t]=i;

// 碎片序号作为下标,分区序号作为值,这样就可以直接按碎片序号循环计算所需时间。


B - b

One day Vasya heard a story: “In the city of High Bertown a bus number 62 left from the bus station. It had n grown-ups and m kids…”

The latter events happen to be of no importance to us. Vasya is an accountant and he loves counting money. So he wondered what maximum and minimum sum of money these passengers could have paid for the ride.

The bus fare equals one berland ruble in High Bertown. However, not everything is that easy — no more than one child can ride for free with each grown-up passenger. That means that a grown-up passenger who rides with his k (k > 0) children, pays overall k rubles: a ticket for himself and (k - 1) tickets for his children. Also, a grown-up can ride without children, in this case he only pays one ruble.

We know that in High Bertown children can’t ride in a bus unaccompanied by grown-ups.

Help Vasya count the minimum and the maximum sum in Berland rubles, that all passengers of this bus could have paid in total.

Input:

The input file consists of a single line containing two space-separated numbers n and m (0 ≤ n, m ≤ 10 5 ) — the number of the grown-ups and the number of the children in the bus, correspondingly.

Output:

If n grown-ups and m children could have ridden in the bus, then print on a single line two space-separated integers — the minimum and the maximum possible total bus fare, correspondingly.

Otherwise, print “Impossible” (without the quotes).

Example:

Input:

1 2

Output:

2 2

Input:

0 5

Output:

Impossible

Input:

2 2

Output:

2 3

Note:

In the first sample a grown-up rides with two children and pays two rubles.

In the second sample there are only children in the bus, so the situation is impossible.

  • In the third sample there are two cases:

  • Each of the two grown-ups rides with one children and pays one ruble for the tickets. In this case the passengers pay two rubles in total.

  • One of the grown-ups ride with two children’s and pays two rubles, the another one rides alone and pays one ruble for himself. So, they pay three rubles in total.


Code:

#include <stdio.h>
int main (void)
{
    int n,m;
    scanf("%d%d",&n,&m);
    if (n==0 && m!=0)
        printf("Impossible\n");
    else if (n==0 && m==0)
        printf("0 0\n");
    else if (m==0)
        printf("%d %d\n",n,n);
    else if (n<=m)
        printf("%d %d\n",m,n+m-1); 
    else
        printf("%d %d\n",n,n+m-1);
    return 0;
}

// 考虑特殊情况:n==0,m==0。


C - c

Paul hates palindromes. He assumes that string s is tolerable if each its character is one of the first p letters of the English alphabet and s doesn’t contain any palindrome contiguous substring of length 2 or more.

Paul has found a tolerable string s of length n. Help him find the lexicographically next tolerable string of the same length or else state that such string does not exist.

Input:

The first line contains two space-separated integers: n and p (1 ≤ n ≤ 1000; 1 ≤ p ≤ 26). The second line contains string s, consisting of n small English letters. It is guaranteed that the string is tolerable (according to the above definition).

Output:

If the lexicographically next tolerable string of the same length exists, print it. Otherwise, print “NO” (without the quotes).

Example:

Input:

3 3
cba

Output:

NO

Input:

3 4
cba

Output:

cbd

Input:

4 4
abcd

Output:

abda

Note:

String s is lexicographically larger (or simply larger) than string t with the same length, if there is number i, such that s*1 = *t 1 , …, s i  = t i , s i  + 1 > t i  + 1.

The lexicographically next tolerable string is the lexicographically minimum tolerable string which is larger than the given one.

A palindrome is a string that reads the same forward or reversed.


Code:

#include <stdio.h>
//定义常量数组,方便处理。
const char* st = " abcdefghijklmnopqrstuvwxyz";
int main (void)
{
    int n,q;
    char s[1010];
    scanf("%d%d",&n,&q);
    getchar();              //注意读取回车
    for (int i=1;i<=n;i++)
        s[i]=getchar();
    s[-1]='A';s[0]='A';     //为判断s[1]做准备
    if (q<2)
    {
        printf("NO\n");
        return 0;
    }
    if (n==1)
    {
        if (s[1]==st[q])
            printf("NO\n");
        else
            printf("%c\n",s[1]+1);
        return 0;
    }
    // 两种特殊情况事先判断

    int i=n;
    do
    {   // 注解(1)
        s[i]++;
        while (s[i]>st[q])
        {
            i--;
            if (i==0)
            {
                printf("NO\n");
                return 0;
            }
            s[i]++;
        }
    }
    while (s[i]==s[i-1] || s[i]==s[i-2]);
    //字符串中不含回文子串 == 字符串中任意字母与前两个字母不相同

    for (int t=i+1;t<=n;t++)
    {   //注解(2)
        s[t]='a';
        while (s[t]==s[t-1] || s[t]==s[t-2])
            s[t]++;
    }
    for (int t=1;t<=n;t++)
        putchar(s[t]);
    printf("\n");
    return 0;
}

// 注解(1):

// 从第 n 位开始,当前位字母递增,若与前两位字母不相同,则找到目标字符串。

// 若递增字母超过所要求的字典序列,即 s[i]>st[q],则左移一位,即 i–,从当前位开始递增。

// 重复上述操作直至找到目标字符串。

// 若 i==0 ,说明 s[1] 已递增至超过字典序列,即找不到所要求的目标字符串,则输出 NO 。

// 注解(2):

// 若有发生移位,则进入循环。为满足字典序最小,则由左向右,每位从 ‘a’ 开始递增,直至满足与前两位不相等。


D - d

You have a nuts and lots of boxes. The boxes have a wonderful feature: if you put x(x ≥ 0) divisors (the spacial bars that can divide a box) to it, you get a box, divided into x + 1 sections.

You are minimalist. Therefore, on the one hand, you are against dividing some box into more than k sections. On the other hand, you are against putting more than v*nuts into some section of the box. What is the minimum number of boxes you have to use if you want to put all the nuts in boxes, and you have *b divisors?

Please note that you need to minimize the number of used boxes, not sections. You do not have to minimize the number of used divisors.

Input:

The first line contains four space-separated integers k, a, b, v (2 ≤ k ≤ 1000; 1 ≤ a, b, v ≤ 1000) — the maximum number of sections in the box, the number of nuts, the number of divisors and the capacity of each section of the box.

Output:

Print a single integer — the answer to the problem.

Example:

Input:

3 10 3 3

Output:

2

Input:

3 10 1 3

Output:

3

Input:

100 100 1 1000

Output:

1

Note:

In the first sample you can act like this:

  • Put two divisors to the first box. Now the first box has three sections and we can put three nuts into each section. Overall, the first box will have nine nuts.
  • Do not put any divisors into the second box. Thus, the second box has one section for the last nut.

In the end we’ve put all the ten nuts into boxes.

The second sample is different as we have exactly one divisor and we put it to the first box. The next two boxes will have one section each.


Code:

#include <stdio.h>
int main (void)
{
    int sec,nut,div,cap;
    scanf("%d%d%d%d",&sec,&nut,&div,&cap);
    int temp=nut/cap;               //按每份里cap个nut,将nut分为temp份
    if (nut % cap != 0) temp++;     //剩余不够cap个的nut单独成为一份
    int box=0;
    while (div>0 && temp>0)         //当分隔板用完或nut用完,则退出循环
    {
        if (div>=sec-1)             //如果剩余分隔板够一个满隔板的盒子
        {
            div-=sec-1;             //减去组成一个满隔板盒子所需的隔板数
            temp-=sec;              //减去组成一个满隔板盒子的隔间数
        }
        else
        {
            temp-=div+1;            //减去剩余分隔板所能组成的隔间数
            div=0;                  //分隔板已用完
        }
        box++;                      //每循环一次,代表填了一个盒子
    }
    if (temp>0)                     //如果nut还有剩
        box+=temp;                  //则每份nut自成一个盒子
    printf("%d\n",box);
    return 0;
}

E - e

On her way to programming school tiger Dasha faced her first test — a huge staircase!

img

The steps were numbered from one to infinity. As we know, tigers are very fond of all striped things, it is possible that it has something to do with their color. So on some interval of her way she calculated two values — the number of steps with even and odd numbers.

You need to check whether there is an interval of steps from the l-th to the r-th(1 ≤ l ≤ r), for which values that Dasha has found are correct.

Input:

In the only line you are given two integers a, b (0 ≤ a, b ≤ 100) — the number of even and odd steps, accordingly.

Output:

In the only line print “YES”, if the interval of steps described above exists, and “NO” otherwise.

Example:

Input:

2 3

Output:

YES

Input:

3 1

Output:

NO

Note:

In the first example one of suitable intervals is from 1 to 5. The interval contains two even steps — 2 and 4, and three odd: 1, 3 and 5.


Code:

#include <stdio.h>
#include <math.h>
int main (void)
{
    int a,b;
    scanf("%d%d",&a,&b);
    if (a==0 && b==0)
        printf("NO\n");
    else if (fabs(a-b)>1)
        printf("NO\n");
    else
        printf("YES\n");
    return 0;
}

// 注意:不存在某个队列同时没有奇数和偶数。所以当 a==0 && b==0 时,输出 NO。


F - f

Running with barriers on the circle track is very popular in the country where Dasha lives, so no wonder that on her way to classes she saw the following situation:

The track is the circle with length L, in distinct points of which there are *n*barriers. Athlete always run the track in counterclockwise direction if you look on him from above. All barriers are located at integer distance from each other along the track.

Her friends the parrot Kefa and the leopard Sasha participated in competitions and each of them ran one lap. Each of the friends started from some integral point on the track. Both friends wrote the distance from their start along the track to each of the n barriers. Thus, each of them wrote n integers in the ascending order, each of them was between 0 and L - 1, inclusively.

img

Consider an example. Let L = 8, blue points are barriers, and green points are Kefa’s start (A) and Sasha’s start (B). Then Kefa writes down the sequence [2, 4, 6], and Sasha writes down [1, 5, 7].

There are several tracks in the country, all of them have same length and same number of barriers, but the positions of the barriers can differ among different tracks. Now Dasha is interested if it is possible that Kefa and Sasha ran the same track or they participated on different tracks.

Write the program which will check that Kefa’s and Sasha’s tracks coincide (it means that one can be obtained from the other by changing the start position). Note that they always run the track in one direction — counterclockwise, if you look on a track from above.

Input:

The first line contains two integers n and L (1 ≤ n ≤ 50, n ≤ L ≤ 100) — the number of barriers on a track and its length.

The second line contains n distinct integers in the ascending order — the distance from Kefa’s start to each barrier in the order of its appearance. All integers are in the range from 0 to L - 1 inclusively.

The second line contains n distinct integers in the ascending order — the distance from Sasha’s start to each barrier in the order of its overcoming. All integers are in the range from 0 to L - 1 inclusively.

Output:

Print “YES” (without quotes), if Kefa and Sasha ran the coinciding tracks (it means that the position of all barriers coincides, if they start running from the same points on the track). Otherwise print “NO” (without quotes).

Example:

Input:

3 8
2 4 6
1 5 7

Output:

YES

Input:

4 9
2 3 5 8
0 1 3 6

Output:

YES

Input:

2 4
1 3
1 2

Output:

NO

Note:

The first test is analyzed in the statement.


Code:

#include <stdio.h>
int main (void)
{
    int n,l;
    int a[110],d1[110],d2[110];
    scanf("%d%d",&n,&l);
    for (int i=1;i<=n;i++)
    {
        if (i==1)
            scanf("%d",&a[i]);
        else
        {
            scanf("%d",&a[i]);
            d1[i-1]=a[i]-a[i-1];    //用d[i-1]数组存储a[i]和a[i-1]的距离
        }
    }
    d1[n]=l-a[n]+a[1];              //d[n]存储a[n]和a[1]的距离
    for (int i=1;i<=n;i++)
    {
        if (i==1)
            scanf("%d",&a[i]);
        else
        {
            scanf("%d",&a[i]);
            d2[i-1]=a[i]-a[i-1];
        }
    }
    d2[n]=l-a[n]+a[1];
    for (int i=1;i<=n;i++)          //以d1的第i位为起点
    {
        int k=i,t=1;
        while (d1[k]==d2[t])        //d1从第i位开始,d2从第1位开始,逐位比较是否都相等
        {
            k++;
            if (k>n) k=1;           //边界处理
            t++;                    //t用来为d2数组计数
            if (t>n)                //如果t大于n,说明两数组各位均相等
            {
                printf("YES\n");
                return 0;
            }
        }
    }
    printf("NO\n");
    return 0;
}

// 用数组存储相邻障碍物之间的距离,其中一个数组通过枚举不同起点与另一个数组同一起点开始逐位比较,看两数组是否各位均相等。


G - g

After overcoming the stairs Dasha came to classes. She needed to write a password to begin her classes. The password is a string of length n which satisfies the following requirements:

  • There is at least one digit in the string,
  • There is at least one lowercase (small) letter of the Latin alphabet in the string,
  • There is at least one of three listed symbols in the string: ‘#’, ‘*’, ‘&’.

img

Considering that these are programming classes it is not easy to write the password.

For each character of the password we have a fixed string of length m, on each of these n strings there is a pointer on some character. The i-th character displayed on the screen is the pointed character in the i-th string. Initially, all pointers are on characters with indexes 1 in the corresponding strings (all positions are numbered starting from one).

During one operation Dasha can move a pointer in one string one character to the left or to the right. Strings are cyclic, it means that when we move the pointer which is on the character with index 1 to the left, it moves to the character with the index m, and when we move it to the right from the position m it moves to the position 1.

You need to determine the minimum number of operations necessary to make the string displayed on the screen a valid password.

Input:

The first line contains two integers n, m (3 ≤ n ≤ 50, 1 ≤ m ≤ 50) — the length of the password and the length of strings which are assigned to password symbols.

Each of the next n lines contains the string which is assigned to the i-th symbol of the password string. Its length is m, it consists of digits, lowercase English letters, and characters ‘#’, ‘*’ or ‘&’.

You have such input data that you can always get a valid password.

Output:

Print one integer — the minimum number of operations which is necessary to make the string, which is displayed on the screen, a valid password.

Example:

Input:

3 4
1**2
a3*0
c4**

Output:

1

Input:

5 5
#*&#*
*a1c&
&q2w*
#a3c#
*&#*&

Output:

3

Note:

In the first test it is necessary to move the pointer of the third string to one left to get the optimal answer.

img

In the second test one of possible algorithms will be:

  • to move the pointer of the second symbol once to the right.
  • to move the pointer of the third symbol twice to the right.

img


Code:

#include <stdio.h>
#include <math.h>
int main (void)
{
    int n,m;
    char s[60][60];
    int chr[60],abc[60],dig[60];    //三个数组分别储存第n个字符串中转到特殊字符,字母,数字的最少步数
    scanf("%d%d",&n,&m);
    if (m==1)                       //特殊情况,若字符串长度为1,则直接输出0
    {
        printf("0\n");
        return 0;
    }
    int mid=m/2;
    for (int i=1;i<=n;i++)
    {                               
        getchar();                  //读取回车
        s[i][0]=getchar();          //字符串第1个字符存储在第0位
        for (int t=1;t<=mid;t++)    //第1个字符的右端字符存储在第1~mid位
            s[i][t]=getchar();
        if (m%2==0)                 //奇偶情况特殊处理
            s[i][-mid]=s[i][mid];
        else
            s[i][-mid]=getchar();
        for (int t=-mid+1;t<0;t++)   //第1个字符的左端字符存储在第-1~-mid位
            s[i][t]=getchar();
    }
    for (int i=1;i<=n;i++)           //计算第i个字符串转到三种字符各需要的最少步数
    {
        chr[i]=abc[i]=dig[i]=50;
        for (int t=-mid;t<=mid;t++)
        {
            if (s[i][t]>='0' && s[i][t]<='9')
            {
                if (fabs(t)<dig[i])
                    dig[i]=fabs(t);
            }
            else if (s[i][t]>='a' && s[i][t]<='z')
            {
                if (fabs(t)<abc[i])
                    abc[i]=fabs(t);
            }
            else
            {
                if (fabs(t)<chr[i])
                    chr[i]=fabs(t);
            }
        }
    }
    int min=150;
    for (int i=1;i<=n;i++)              //三重循环,i为特殊字符,j为字母,k为数字,枚举所有组合
    {
        for (int j=1;j<=n;j++)
            if (j!=i)
            {
                for (int k=1;k<=n;k++)
                    if (k!=i && k!=j)
                    {
                        int t=chr[i]+abc[j]+dig[k];
                        if (t < min)
                            min=t;
                    }
            }
    }
    printf("%d\n",min);
    return 0;
}

// 将第一个字符存在第0位,左右两端字符存在第 -i 位和第 i 位,位数的绝对值即表示转到此处所需要的步数。然后计算出各个字符串转到三种字符各需要的最少步数。最后通过三重循环枚举所有组合求出转到满足题目条件所需的最少步数。

// 注意 m 的奇偶性和 m==1 时的特殊情况。


H - h

Dasha logged into the system and began to solve problems. One of them is as follows:

Given two sequences a and b of length n each you need to write a sequence c of length n, the i-th element of which is calculated as follows: c i  = b i  - a i .

About sequences a and b we know that their elements are in the range from l to r. More formally, elements satisfy the following conditions: l ≤ a i  ≤ r and l ≤ b i  ≤ r. About sequence c we know that all its elements are distinct.

img

Dasha wrote a solution to that problem quickly, but checking her work on the standard test was not so easy. Due to an error in the test system only the sequence*a* and the compressed sequence of the sequence c were known from that test.

Let’s give the definition to a compressed sequence. A compressed sequence of sequence c of length n is a sequence p of length n, so that p i equals to the number of integers which are less than or equal to c i in the sequence c. For example, for the sequence c = [250, 200, 300, 100, 50] the compressed sequence will be p = [4, 3, 5, 2, 1]. Pay attention that in c all integers are distinct. Consequently, the compressed sequence contains all integers from 1 to n inclusively.

Help Dasha to find any sequence b for which the calculated compressed sequence of sequence c is correct.

Input:

The first line contains three integers n, l, r (1 ≤ n ≤ 105, 1 ≤ l ≤ r ≤ 109) — the length of the sequence and boundaries of the segment where the elements of sequences*a* and b are.

The next line contains n integers a 1 ,  a 2 ,  …,  a n (l ≤ a i  ≤ r) — the elements of the sequence a.

The next line contains n distinct integers p 1 ,  p 2 ,  …,  p n (1 ≤ p i  ≤ n) — thecompressed sequence of the sequence c.

Output:

If there is no the suitable sequence b, then in the only line print “-1”.

Otherwise, in the only line print n integers — the elements of any suitable sequence b.

Example:

Input:

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

Output:

3 1 5 4 2 

Input:

4 2 9
3 4 8 9
3 2 1 4

Output:

2 2 2 9 

Input:

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

Output:

-1

Note:

Sequence b which was found in the second sample is suitable, because calculated sequence c = [2 - 3, 2 - 4, 2 - 8, 9 - 9] = [ - 1,  - 2,  - 6, 0] (note that c i  = b i  - a i ) has compressed sequence equals to p = [3, 2, 1, 4].


Code:

#include <stdio.h>
int main (void)
{
    int a[100010],c[100010];
    long long b[100010];            //b有可能超过int
    int n,l,r;
    scanf("%d%d%d",&n,&l,&r);
    int d=r-l;
    for (int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for (int i=1;i<=n;i++)
    {                               //以数据作下标,i作值,实现免排序
        int t;
        scanf("%d",&t);
        c[t]=i;
    }

    int t=0;                        //t表示每次将低于边界
    for (int i=1;i<=n;i++)
    {                               //c[i]表示递增列中第i位在数组中对应的位置
        b[c[i]]=a[c[i]]+i+t;        //只要前面有数被提高,后面的数都要先加上之前提高的值,再参与判断
        if (b[c[i]]<b[c[1]])        //以b[c[1]]作边界
        {                           //t表示每次将低于边界的数提高到边界需要增加的值
            t+=b[c[1]]-b[c[i]];     //注意t需要累加,而非重新赋值
            b[c[i]]=b[c[1]];
        }
        if (b[c[i]]>b[c[1]]+d)      //若超过上界则无解
        {
            printf("-1\n");
            return 0;
        }
    }
    d=b[c[1]]-l;                    //b[c[1]]和l的差值
    for (int i=1;i<=n;i++)
    {
        if (i==1)
            printf("%I64d",b[i]-d);
        else
            printf(" %I64d",b[i]-d);
    }
    printf("\n");
    return 0;
}

// 巧妙处理 c 数组,实现免排序。

// b 数组=a 数组+c 数组,c 数组值从 1~n。

// 以 b1 为边界,bi 先加上 t(即之前的数所累积的差值)

// 若 bi 小于边界,则 t 累加上 bi 与边界的差值,然后 bi=b1;若 bi 大于边界加区间长度(即 b1+d),则无解。


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值