CodeForces水一水
B. Binary String Constructing(Div3—构造),CodeForces - 1004C(Div2—思维),CodeForces - 962D(Div2—较为精辟的解法),1055B - Alice and Hairdresser(思维),1088A. Ehab and another construction problem(暴力与O(1)),
1088C. Ehab and a 2-operation task(通过操作使数组递增)
B. Binary String Constructing(Div3—构造)
题意:给出a,b,x,构造一个01串,有a个0,b个1。这个01串刚好有x个 S[i] 使得S[i] != S[i+1]。
思路:对于x,我们很容易就可以想到先输出x/2对0和1(n对0和1交错出现可以提供2*n-1个符合题意的S[i]),然后将剩余的0和剩余的1连续输出(提供1个符合条件的S[i],这样就刚好是x个符合条件的S[i]了,需要注意的是,我们要优先将个数多的放在前面,例如,有10个1,5个0的话,我们先输出x/2个“10”,否则,输出x/2个“01”)。
还有一个情况就是x刚好整除2,这时候得额外处理一个。
比如4 3 2
就需要输出0111000,而不是0100011
之前没有判断x刚好整除2,wa了一个
Input
1 | 50 47 18 |
Output
1 | 0101010101010101010000000000000000000000000000000000000000011111111111111111111111111111111111111 |
Answer
1 | 0101010101010101011111111111111111111111111111111111111100000000000000000000000000000000000000000 |
1 |
|
CodeForces - 1004C(Div2—思维)
题目大意:有n个数,每个数只能与自己后面的数配对,相同的配对只算一个,求配对的数量.
最开始用set暴力求解,当然是TLE了。
我们只需从1号位置开始检查,判断1号位置后面有多少个不同的数字,然后再从2号位置开始检查,判断2号位置后面有多少个不同的数字,依此类推,最后将所有的结果加起来就可以了(注意,从i号位置检查后面的数时,需要先判读这个位置的数是否以及出现过)。 如果直接暴力检查的话,肯定会tle,所以,我们先预处理出每个位置后面不同数字的个数,然后累加。
1 | /* |
CodeForces - 962D(Div2—较为精辟的解法)
题意:给出一个整数序列。选择其中最小且出现两次(或以上)的数,把最左边的两个从序列中移除, 然后把它们的和放到它们的后面第一位。不断重复上述过程,直到序列中的每个数都是唯一的。 输出最后的序列。
这道题可以用优先队列,set和map来做,挑了一种比较精辟的解法
1 | /* |
1055B - Alice and Hairdresser(div2—思维)
标签是写着并查集和模拟,刚开始想到用并查集,但是后来行不通,知道得分集合,还得合并集合,但是不知道怎么存储,然后看了别的代码才知道不用那么麻烦,直接判断左右数字就可以确定一个集合,还是太年轻。
题目大意:
Alice去剪发,一共有n根头发,长度大于l的头发需要剪,如果一个区间中的头发长度全部大于l,那么可以一次给这个区间的所有头发都剪,
输入给出0是询问需要剪几次。
给出1是第p根头发长了d长度
题解:
首先总计一下给出的数据需要剪的区间有几个,也就是需要剪的总次数是多少。
当给第p根头发增长了d后,以前小于l,增长之后大于l的话
如果左右两边都大于l,那么现在第p根也大于l了,就可以和左右两边连成片,一次减掉,所以要剪的总次数减一。
如果左右两边都小于等于l,那么第p根现在需要剪了,就要剪的总次数加一。
其他情况都不影响剪的总次数。
参考:https://blog.csdn.net/hxxjxw/article/details/83990002
1 | /* |
1088A. Ehab and another construction problem(暴力与O(1))
给定一个n,找到两个数a,b{1 <= a,b <= n}
使得a被b整除且ab>n
且a/b<n
符合条件的a,b非常多,任意输出一个即可
解法1—-暴力
暴力的话就是用两个for循环去暴力枚举a,b,然后找出符合条件的a,b输出就行了。
解法2—-确定一个数
我们可以确定b为2,那么a的值就是n-n%2
,可以得到如下证明:
(n-n%2)的意思:就是在小于等于n的范围内找出最大能被模2的数,例如11,n%2=11%2=1
,那么n-n%2=10
,又如12,n%2=12%2=0
,那么n-n%2=12
。
然后的话可以证明下,首先看范围,当n>=2
时,b肯定是满足[1, n]
,看上面的两个例子,当n是奇数时,因为a肯定是得到偶数,因为n是奇数,又是减法,故此时a就是a-1
了,符合条件,当n是偶数时,那么是根据上式得出的a就是n。
当n是奇数时,a为n-1
,b为2,那么就有a*b=2*(n-1)
,当n>2
时满足a*b>n
,同时有(n-1)/2<n
当n是偶数时,a为n
, b为2,那么就有a*b=2*n
,当n>=1
时满足a*b>n
,同时有n/2<n
根据上面可以得出,当n>=2时,固定b为2,那么a的值就是n-n%2
。
可以看出固定b为2的情况容易证明,但是固定b为3(或者3以后)的情况就难以讨论。1
2
3
4
5
6
7
8
9
10
11
using namespace std;
int main()
{
int x;
cin >> x;
if (x==1)
cout << -1;
else
cout << x-x%2 << ' ' << 2;
}
1088C. Ehab and a 2-operation task(通过操作使数组递增)
给定一个序列 两种操作:
- 选定一个i,将[1,i]内的所有数加上x
- 选定一个i,将[i,j]内所有数模x
让你在不大于n+1次操作后使序列严格递增,输出所进行的操作
解法看上图,下面代码用的是Second solution
1 | /* |