Codeforces Round #629 (Div. 3) A~C

昨天晚上打了一场CF,由于网卡,还有英语题读题较慢,所以只AC了3道题->_->

(准确的来说AC了2道,因为最后凌晨的时候我这边网络直接崩了,连接不上codefores,就没提交成功QAQ)
好了,开始进入正题:

A:

time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given two positive integers aa and bb. In one move you can increase aa by 11 (replace aa with a+1a+1). Your task is to find the minimum number of moves you need to do in order to make aa divisible by bb. It is possible, that you have to make 00 moves, as aa is already divisible by bb. You have to answer tt independent test cases.

Input

The first line of the input contains one integer tt (1t1041≤t≤104) — the number of test cases. Then tt test cases follow.

The only line of the test case contains two integers aa and bb (1a,b1091≤a,b≤109).

Output

For each test case print the answer — the minimum number of moves you need to do in order to make aa divisible by bb.

Example
input
Copy
5
10 4
13 9
100 13
123 456
92 46
output
Copy
2
5
4
333
0
这个题的大意就是a被b整除的最小的位移是多少,就是一道数学签到题,不过也有需要注意的地方。
注: 1> a不能--,只能++;
2> 当a==b时,直接输出0就行
3> a可能小于b
总之,分类讨论就行:,所以可以得到如下代码
 1 #include<stdio.h>
 2 int main(void)
 3 {
 4     int t,a,b;
 5     scanf("%d",&t);
 6     while(t--)
 7     {
 8         scanf("%d %d",&a,&b);
 9         if(a%b==0)
10             printf("0\n");
11         else if(a>b)
12             printf("%d\n",b-a%b);
13         else if(a<b)
14             printf("%d\n",b-a);
15     }
16     return 0;
17 }
View Code

好了,我们来看第二道题吧;

time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

For the given integer nn (n>2n>2) let's write down all the strings of length nn which contain n2n−2 letters 'a' and two letters 'b' in lexicographical (alphabetical) order.

Recall that the string ss of length nn is lexicographically less than string tt of length nn, if there exists such ii (1in1≤i≤n), that si<tisi<ti, and for any jj (1j<i1≤j<i) sj=tjsj=tj. The lexicographic comparison of strings is implemented by the operator < in modern programming languages.

For example, if n=5n=5 the strings are (the order does matter):

  1. aaabb
  2. aabab
  3. aabba
  4. abaab
  5. ababa
  6. abbaa
  7. baaab
  8. baaba
  9. babaa
  10. bbaaa

It is easy to show that such a list of strings will contain exactly n(n1)2n⋅(n−1)2 strings.

You are given nn (n>2n>2) and kk (1kn(n1)21≤k≤n⋅(n−1)2). Print the kk-th string from the list.

Input

The input contains one or more test cases.

The first line contains one integer tt (1t1041≤t≤104) — the number of test cases in the test. Then tt test cases follow.

Each test case is written on the the separate line containing two integers nn and kk (3n105,1kmin(2109,n(n1)2)3≤n≤105,1≤k≤min(2⋅109,n⋅(n−1)2).

The sum of values nn over all test cases in the test doesn't exceed 105105.

Output

For each test case print the kk-th string from the list of all described above strings of length nn. Strings in the list are sorted lexicographically (alphabetically).

Example
input
Copy
7
5 1
5 2
5 8
5 10
3 1
3 2
20 100
output
Copy
aaabb
aabab
baaba
bbaaa
abb
bab
aaaaabaaaaabaaaaaaaa

 这道题是一个典型的字符串模拟题,还加了一点组合数学的题目。

题意就是给你两个数字n和k输出长度为n的第k种字符串。还是蛮有意思的。,让我们看看这道题的解法吧。

也算是找规律题,让我们结合代码来看看吧

 1 #include<stdio.h>
 2 #include<math.h>
 3 int main(void)
 4 {
 5     long long  t,n,k,l2;
 6     scanf("%lld",&t);//循环计算的次数 
 7     while(t--)
 8     {
 9         scanf("%lld%lld",&n,&k);//n是字符串的长度 
10         long long  y=(sqrt(8*k+1)-1)/2;//计算层数,也就是第一个b向左移动的距离 
11         long long  x=k-(y*y+y)/2;//计算剩下的步数,也就是第二个b移动的距离 
12         long long  l1=n-y;//第一个b顺序的位置 
13         if(x==0)//这里是特例,当不剩下步数的时候第二个b就在第一个b的后一个位置 
14         l2=l1+1;
15         else//否则计算第二个b的位置,第一个b的位置要+1 
16         l2=n-x+1,l1--;
17         for(int i=1;i<=n;++i)//这里就是输出字符串 
18         {
19             if(i==l1||i==l2)
20             printf("b");
21             else 
22             printf("a");
23         }
24         printf("\n");
25     }
26     return 0;
27 }
View Code

注意这里要用 long long,因为数据范围超过了int!!!(因为我第一次就是用的int,然后wa了,,调试了十多分钟才知道数据超了)

第三题如下:

time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

A number is ternary if it contains only digits 00, 11 and 22. For example, the following numbers are ternary: 10221022, 1111, 2121, 20022002.

You are given a long ternary number xx. The first (leftmost) digit of xx is guaranteed to be 22, the other digits of xx can be 00, 11 or 22.

Let's define the ternary XOR operation ⊙ of two ternary numbers aa and bb (both of length nn) as a number c=abc=a⊙b of length nn, where ci=(ai+bi)%3ci=(ai+bi)%3 (where %% is modulo operation). In other words, add the corresponding digits and take the remainders of the sums when divided by 33. For example, 1022211021=2121010222⊙11021=21210.

Your task is to find such ternary numbers aa and bb both of length nn and both without leading zeros that ab=xa⊙b=x and max(a,b)max(a,b) is the minimum possible.

You have to answer tt independent test cases.

Input

The first line of the input contains one integer tt (1t1041≤t≤104) — the number of test cases. Then tt test cases follow. The first line of the test case contains one integer nn (1n51041≤n≤5⋅104) — the length of xx. The second line of the test case contains ternary number xx consisting of nn digits 0,10,1 or 22. It is guaranteed that the first digit of xx is 22. It is guaranteed that the sum of nn over all test cases does not exceed 51045⋅104 (n5104∑n≤5⋅104).

Output

For each test case, print the answer — two ternary integers aa and bb both of length nn and both without leading zeros such that ab=xa⊙b=x and max(a,b)max(a,b) is the minimum possible. If there are several answers, you can print any.

Example
input
Copy
4
5
22222
5
21211
1
2
9
220222021
output
Copy
11111
11111
11000
10211
1
1
110111011
110111010

 第三题就是有一个贪心+暴力,只要读懂题意,秒懂,然后做出来;

这道题题意建议找度娘翻译一下;

开始的时候有点懵,还以为会牵扯到位运算(毕竟位运算,我是我都没怎么刷过题);

然后长达十五分钟的题意翻译就开始了,就是求一个序列拆分为两个序列怎样最小,是不是很简单=_=;

关键点就是找到串中为1的数字,然后记录该点的位置坐标,第一个串开始从0开始输出主串数字的一半,当碰到1的时候就停止,后面的元素全都是0;

如果falg!=0第二个串falg之前的元素输出主串的一半(包括第flag个元素),后续元素就输出主串元素;

如果flag==0,那就意味着主串没有为1的数字,也就是说主串是均分的,那么所有元素输出主串的一般就行;

废话不多说,直接上代码,第一遍的代码;

#include<stdio.h>
#include<string.h>
char a[500005];
int b[500005],c[500005];//f分别储存两个分解串; 
int main(void)
{
    int t,l;//l即为n 
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%s",&l,a);
        int flag=0;
        for(int i=0;i<l;++i)
        {
            if(a[i]=='1')
            {
            flag=i;
            b[i]=1;
            break;
            }
            else
            {
                b[i]=(a[i]-'0')/2;
            }
        }
        if(flag)
        {
        for(int i=flag+1;i<l;i++)
        b[i]=0;
    }
        for(int i=0;i<l;++i)
        {
            if(flag)
            {
            if(i<=flag)
            {
                c[i]=(a[i]-'0')/2;
            }
            else
            {
                c[i]=a[i]-'0';
            }
        }
        else
        {
            c[i]=(a[i]-'0')/2;
        }
        }
        for(int i=0;i<l;i++)
        printf("%d",b[i]);
        printf("\n");
        for(int i=0;i<l;++i)
        printf("%d",c[i]);
        printf("\n");
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
    }
    return 0;
}
View Code

然后就,,,,,

所以这个肯定是有优化的,如果你没想到,聪敏的你肯定想到了优化方法;

1> 第一个优化就是那两个串的数组可以去掉,直接输出;

2>第二个优化就是memset可以去掉,因为每次输出串的长度都是已知的,所以不会造成数据出错,也就不用清空(也还是能省点时间的);

然后优化代码如下:

#include<stdio.h>
#include<string.h>
char a[500005];
int main(void)
{
    int t,l;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%s",&l,a);
        int flag=0;
        for(int i=0;i<l;++i)
        {
            if(a[i]=='1')
            {
            flag=i;
            printf("1");
            break;
            }
            else
            printf("%d",(a[i]-'0')/2);
        }
        if(flag)
        {
        for(int i=flag+1;i<l;i++)
        printf("0");
        }
        printf("\n");
        for(int i=0;i<l;++i)
        {
            if(flag)
            {
            if(i<=flag)
                printf("%d",(a[i]-'0')/2);
            else
            printf("%d",a[i]-'0');
            }
        else
            printf("%d",(a[i]-'0')/2);
        }
        printf("\n");
    }
    return 0;
}

这次前三道题目基本上都与数学有一定的关系,做起来的感觉就是有思路,不过把思路转换成代码确实花费了大量的实践=_=,这可能就是基础知识不牢吧,这次rating定位赛,我的rating

定位在1428,本来该1500+的,,,QAQ,希望下次DIV赛能上1500+;

posted @ 2020-03-27 21:24  MangataTS  阅读(199)  评论(0编辑  收藏  举报