2023.1.9(总结)

今天主要是对昨天的比赛的一个总结。

A

You are given an integer kk. Find the largest integer xx, where 1 \le x < k1≤x<k, such that x! + (x - 1)!^\daggerx!+(x−1)!† is a multiple of ^\ddagger‡ kk, or determine that no such xx exists.

^\dagger† y!y! denotes the factorial of yy, which is defined recursively as y! = y \cdot (y-1)!y!=y⋅(y−1)! for y \geq 1y≥1 with the base case of 0! = 10!=1. For example, 5! = 5 \cdot 4 \cdot 3 \cdot 2 \cdot 1 \cdot 0! = 1205!=5⋅4⋅3⋅2⋅1⋅0!=120.

^\ddagger‡ If aa and bb are integers, then aa is a multiple of bb if there exists an integer cc such that a = b \cdot ca=b⋅c. For example, 1010 is a multiple of 55 but 99 is not a multiple of 66.

Input

The first line contains a single integer tt (1 \le t \le 10^41≤t≤104) — the number of test cases. The description of test cases follows.

The only line of each test case contains a single integer kk (2 \le k \le 10^92≤k≤109).

Output

For each test case output a single integer — the largest possible integer xx that satisfies the conditions above.

If no such xx exists, output -1−1.

Sample 1

InputcopyOutputcopy
4
3
6
8
10
2
5
7
9

Note

In the first test case, 2! + 1! = 2 + 1 = 32!+1!=2+1=3, which is a multiple of 33.

In the third test case, 7! + 6! = 5040 + 720 = 57607!+6!=5040+720=5760, which is a multiple of 88.

题意:就是说给你一个数然后然你找出一个数,找出的这个数的阶乘加上减去这个数减1的数的阶乘是给出的那个数的倍数。

分析:

1,首先我们要明确一个特殊的数那就是0!,0!=1,还有一个特殊的条件是如果找不到就输出-1。

2,依据样例来看要找到的数应该就是输入的数减1,那什么时候输出-1呢?那就这个数小于1的时候。

3,综合前面的分析,整个程序的大概就出来了,很好写。

代码如下:

#include<stdio.h>
#include<math.h>
#include<string.h>
int main()
{
    int t;
    scanf("%d",&t);
    for(int i=0;i<t;i++)
    {
        long long k;
        scanf("%lld",&k);
        if(k>0)
        printf("%lld\n",k-1);
        else 
        printf("-1\n");
    }
}

B

Problem Statement

Takahashi is a cashier.

There is a cash register with 1111 keys: 00012345678, and 9. The cash register initially displays 00. Whenever he types the key 00, the displayed number is multiplied by 100100; whenever he types one of the others, the displayed number is multiplied by 1010, and then added by the number written on the key.

Takahashi wants the cash register to display an integer SS. At least how many keystrokes are required to make it display SS?

Constraints

  • 1\leq S\leq 10^{100000}1≤S≤10100000
  • SS is an integer.

Input

The input is given from Standard Input in the following format:

SS

Output

Print the answer in a line.

Sample 1

InputcopyOutputcopy
40004
4

For example, the following four keystrokes make the cash register display 4000440004. Initially, the cash register displays 00.

  • Type the key 4. It now displays 44.
  • Type the key 00. It now displays 400400.
  • Type the key 0. It now displays 40004000.
  • Type the key 4. It now displays 4000440004.

He cannot make it display 4000440004 with three or fewer keystrokes, so 44 should be printed.

Sample 2

InputcopyOutputcopy
1355506027
10

Sample 3

InputcopyOutputcopy
10888869450418352160768000001
27

Note that SS may not fit into a 6464-\operatorname{bit}bit integer type.

题意:收银机有11个键:00、0、1、2、3、4、5、6、7、8和9。收银机最初显示0。每当他输入键0时,显示的数字乘以100;每当他输入其他数字之一时,显示的数字乘以10,然后再加上写在键上的数字。高桥希望收银机显示一个整数S。至少需要多少次按键才能显示S?

分析:

1,首先他是说最少需要多少次,所以我们要找到的是最少的次数。

2,这里有第一个需要注意的点,那就是00,每次是添两个0。

3,我们要明白的是,如果只是乘以10,那每个数字都需要按一次,如果是连续的两个0,那么按一次00是可以解决的。

4,所以我们输入的时候直接利用字符串就行,然后直接测长度,再查找有多少个连续的0,每次找到连续的0就累计0的个数,然后就除以2,用测出的长度的总数减去除以2的0的个数。

5,所以这个题目就是很简单的一个题目,主要是要把题意捋顺。

代码如下:

#include<stdio.h>
#include<math.h>
#include<string.h>
char a[1000005];
long long n,m,i,j;
int main()
{
    gets(a);
    n=strlen(a);
    m=n;
    for(i=1;i<n;i++)
    {
        if(a[i]=='0')
        {
            for(j=i;j<n;j++)
            {
                if(a[j]!='0')
                break;
            }
        m-=((j-i)/2);
        i=j;
        }
    }
    printf("%lld",m);
}

E

MKnez wants to construct an array s_1,s_2, \ldots , s_ns1​,s2​,…,sn​ satisfying the following conditions:

  • Each element is an integer number different from 00;
  • For each pair of adjacent elements their sum is equal to the sum of the whole array.

More formally, s_i \neq 0si​=0 must hold for each 1 \leq i \leq n1≤i≤n. Moreover, it must hold that s_1 + s_2 + \cdots + s_n = s_i + s_{i+1}s1​+s2​+⋯+sn​=si​+si+1​ for each 1 \leq i < n1≤i<n.

Help MKnez to construct an array with these properties or determine that it does not exist.

Input

Each test contains multiple test cases. The first line contains the number of test cases tt (1 \leq t \leq 1001≤t≤100). The description of the test cases follows.

The only line of each test case contains a single integer nn (2 \leq n \leq 10002≤n≤1000) — the length of the array.

Output

For each test case, print "YES" if an array of length nn satisfying the conditions exists. Otherwise, print "NO". If the answer is "YES", on the next line print a sequence s_1,s_2, \ldots, s_ns1​,s2​,…,sn​ satisfying the conditions. Each element should be a non-zero integer in the range [-5000,5000][−5000,5000], i. e. -5000 \leq s_i \leq 5000−5000≤si​≤5000 and s_i \neq 0si​=0 should hold for each 1 \leq i \leq n1≤i≤n.

It can be proved that if a solution exists then there also exists one which satisfies the additional constraints on the range.

If there are several correct answers, print any of them.

Sample 1

InputcopyOutputcopy
2
2
3
YES
9 5
NO

Note

In the first test case, [9,5][9,5] is a valid answer since 9+59+5 (the sum of the two adjacent elements s_1+s_2s1​+s2​) is equal to 9+59+5 (the sum of all elements). Other solutions include [6,-9], [-1,-2], [-5000,5000], \ldots[6,−9],[−1,−2],[−5000,5000],…

For the second test case, let us show why some arrays do not satisfy the constraints:

  • [1,1,1][1,1,1]  — s_1+s_2 = 1+1 = 2s1​+s2​=1+1=2 and s_1+s_2+s_3=1+1+1 = 3s1​+s2​+s3​=1+1+1=3 differ;
  • [1,-1,1][1,−1,1]  — s_1+s_2=1+(-1)=0s1​+s2​=1+(−1)=0 and s_1+s_2+s_3=1+(-1)+1 = 1s1​+s2​+s3​=1+(−1)+1=1 differ;
  • [0,0,0][0,0,0]  — The array ss cannot contain a 00.

This is not a proof, but it can be shown that the answer is "NO".

题意:给你一个数,如果这个数能满足一个数组里面任意相邻的两个数相加等于数组的总数的总和,并且数组里面没有0,就输出YES,并且输出这个数组,如果有多个数组,任意输出一个就行,如果不满足就输出NO。

分析:

1,首先我们需要明确的是,要相邻的两个数相加等于整个数组的值。

2,那么,我们可以确定的是偶数是一定可以的,因为我们可以保持整个数组的值为0,然后相邻的两个数的值也为0。就像1,-1,1,-1这样。

3,那么奇数呢?首先3肯定是不行的,因为无论怎么凑都凑不够,那试试5,5可以分为:1,-2,1,-2,1,这个数组是满足的,那么7呢?7可以分为:2,-3,2,-3,2,-3,2,这个数组也是满足的,所以我们可以确定的是除了3以外的数我们是可以找出数组的,那有什么规律呢?那就是原数除以2再乘以-1就是那个负数,整数就是除以2再减1.

4,所以对于这个题,更关键的是找规律。

代码如下:

#include<stdio.h>
#include<math.h>
#include<string.h>
int main()
{
    int t,n;
    scanf("%d",&t);
    for(int i=0;i<t;i++)
    {
        scanf("%d",&n);
        if(n==3)
        {printf("NO\n");continue;}
        if(n%2==0)
        {
            printf("YES\n");
            int f=1;
            for(int j=0;j<n;j++)
            {
                printf("%d ",f);
                f=-f;
            }
            printf("\n");
        }
        else
        {
            printf("YES\n");
            int l,r;
            l=n/2-1;
            r=l+1;
            for(int j=0;j<n;j++)
            {
                if(j%2)
                printf("%d ",-r);
                else 
                printf("%d ",l);
            }
            printf("\n");
        }
    }
}

F

Problem Statement

We have a playlist with NN songs numbered 1, \dots, N1,…,N.
Song ii lasts A_iAi​ seconds.

When the playlist is played, song 11, song 22, \ldots…, and song NN play in this order. When song NN ends, the playlist repeats itself, starting from song 11 again. While a song is playing, the next song does not play; when a song ends, the next song starts immediately.

At exactly TT seconds after the playlist starts playing, which song is playing? Also, how many seconds have passed since the start of that song?
There is no input where the playlist changes songs at exactly TT seconds after it starts playing.

Constraints

  • 1 \leq N \leq 10^51≤N≤105
  • 1 \leq T \leq 10^{18}1≤T≤1018
  • 1 \leq A_i \leq 10^91≤Ai​≤109
  • The playlist does not change songs at exactly TT seconds after it starts playing.
  • All values in the input are integers.

Input

The input is given from Standard Input in the following format:

NN TT
A_1A1​ \ldots… A_NAN​

Output

Print an integer representing the song that is playing at exactly TT seconds after the playlist starts playing, and an integer representing the number of seconds that have passed since the start of that song, separated by a space.

Sample 1

InputcopyOutputcopy
3 600
180 240 120
1 60

When the playlist is played, the following happens. (Assume that it starts playing at time 00.)

  • From time 00 to time 180180, song 11 plays.
  • From time 180180 to time 420420, song 22 plays.
  • From time 420420 to time 540540, song 33 plays.
  • From time 540540 to time 720720, song 11 plays.
  • From time 720720 to time 960960, song 22 plays.
  • \qquad\vdots⋮

At time 600600, song 11 is playing, and 6060 seconds have passed since the start of that song.

Sample 2

InputcopyOutputcopy
3 281
94 94 94
3 93

Sample 3

InputcopyOutputcopy
10 5678912340
1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000 1000000000
6 678912340 

题意: 我们有一个播放列表,其中有NN首歌,编号为1,N1,…,N。歌曲i持续a i秒。当播放播放列表时,歌曲1、歌曲2、…和歌曲NN按此顺序播放。当歌曲NN结束时,播放列表重复,再次从歌曲11开始。当一首歌在播放时,下一首歌就不播放了;一首歌结束后,下一首歌马上开始。在播放列表开始播放后的TT秒,哪首歌正在播放?还有,从这首歌开始到现在已经过去了多少秒?
 

分析:

1,这个题目我看到之后首先就想到了前缀和,所以初步决定这个题目使用前缀和。

2,我们得到的播放了的秒钟数可能会很大,大到比所有的歌曲的秒数相加的和还大,所以这里有一个很关键的步骤就是取模。

3,取模怎么取?取什么的模?我们确定的是取模在一定程度上和取余差不多,我们取的模就是所有的歌曲的秒数相加的和,也就是前缀和数组的最后一个元素。

4,在取完模之后,找第几首歌曲,和这首歌曲播放到第多少秒就很简单。

代码如下:

#include<stdio.h>
#include<math.h>
#include<string.h>
long long a[100005],b[100005];
int main()
{
    int n;
    long long t;
    scanf("%d%lld",&n,&t);
    for(int i=0;i<n;i++)
    {
        scanf("%lld",a+i);
    }
    b[0]=a[0];
    for(int i=1;i<n;i++)
    {
        b[i]=a[i]+b[i-1];
    }
    t=t%b[n-1];
    for(int i=0;i<n;i++)
    {
        if(b[i]>=t)
        {
            printf("%d ",i+1);
            if(i==0)
            printf("%lld\n",t);
            else 
            printf("%lld\n",t-b[i-1]);
            break;
        }
    }
}

总结:

这次的题目大多偏简单,更多的是对于题目的分析以及理解,还有就是对思维的运用,但是这次的一次考查并查集的题目没有AC,因为当时的状态已经有点不好了,对于题目的把握没有前面那么清醒,最终那个题目因为输出出了问题WA了,后来改了那一行输出,再交就AC了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值