1
2
3
slmgr /ipk W269N-WFGWX-YVC9B-4J6C9-T83GX
slmgr /skms kms.0t.net.cn
slmgr /ato

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <fstream>
using namespace std;

int main() {
ofstream outfile;

outfile.open("1.txt");
outfile << "test1" << endl;
outfile.close();

outfile.open("2.txt");
outfile << "test2" << endl;
outfile.close();
}

C++中一个打开文件的流可以多次打开不同的文件

接下来,我们来学习如何求解线性同余方程。让我们考虑如何求线性方程ax=b(mob m)。对于实数运算下的方程ax=b,由于a存在倒数,因此很容易求解。如果在mod m的运算下,也有像满足ay=1(mob m)这样的a的倒数存在,方程就可以求解了。我们把这样的y叫做a的逆元,记作a^-1。如果能求解逆元,那么就有x=a^-1*xa=a^-1b,也就可以求出x了。由于方程ax=1(mob m)等价于存在整数k使得ax=1+mk,因此稍作变形之后,可以变为求解满足ax-mk=1的x的问题。这个问题可以用extgcd(扩展欧几里得算法)求解。同时,也可以知道如果gcd(a,m)!=1,那么逆元是不存在的。

1
2
3
4
5
int mod_inverse(int a,int m){
int x,y;
extgcd(a,m,x,y);
return (m + x % m) % m;
}

如果a和m不互素,那么ax=b(mob m)就等价于
(a/gcd(a,m))x≡b/gcd(a,m)(mob m/gcd(a,m))
从式子中可以看出,当b无法整除gcd(a,m)时,原方程无解。在有解的情况下,我们有
x≡gcd(a/gcd(a,m))^(-1)*(b/gcd(a,m))(mob m/gcd(a,m))
因此,ax=b(mob m)的解为
x≡a(a/gcd(a,m))^(-1)*(b/gcd(a,m))+(m/gcd(a,m))*k(mob m)(0≤k<gcd(a,m))
需要注意的是这里和实数的情况有所不同,有可能有多解,也有可能无解。

B2165 括号匹配

题目描述

给定只由 $6$ 种括号字符组成的字符串:(, ), [, ], {, }。判断每个字符串是否为“合法括号序列”,合法则输出 YES,否则输出 NO。合法括号序列的定义:

  • 空串合法;
  • 若 A 合法,则 (A), [A], {A} 均合法;
  • 若 A 与 B 均合法,则 AB 合法。

输入格式

第一行一个整数 $T$,表示数据组数。接下来 $T$ 行,每行一个只包含上述 $6$ 种字符的字符串。

输出格式

对于每个字符串,输出一行:

  • 若其为合法括号序列,输出 YES;
  • 否则输出 NO。

输入输出样例 #1

输入 #1

1
2
1
()[]{}

输出 #1

1
YES

输入输出样例 #2

输入 #2

1
2
3
4
5
6
7
6
()
([)]
([]){}
((((
{[()()]}
}{

输出 #2

1
2
3
4
5
6
YES
NO
YES
NO
YES
NO

说明/提示

记单串长度记为 $|S|$。测试数据满足 $1 \leq |S| \leq 10^6$,$1 \leq T \leq 2\times 10^5$,同一输入文件内总长度 $\sum |S| \leq 2\times 10^6$,字符串只包含字符 ()[]{}

解:

我们知道括号像栈一样,遵循 LIFO(后进先出)

比如:
{{}
第二位{是后进的,那么与之匹配的是第三位的}

那么我们用栈的方式思考,
我们把 左括号 认为是无条件push, 右括号 认为是有条件pop,
条件是栈顶的括号一定和右括号匹配
比如(]不符合规则的

还有其他可能的情况需要注意

比如(((它没有右括号所以也是不符合的,
我们可以判断所有push,pop操作后栈顶下标是否>0,大于则代表栈不为空
比如)))
栈顶下标是否<0,如果是则说明少左括号了

答案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <bits/stdc++.h>
using namespace std;
char arr[1000000];
int main(){
int N;
cin >> N;
for(int i = 0;i<N;i++){
int sz = 0;
string s;
cin >> s;
int f = 0;
for(int j = 0;j<s.size();j++){
if(s[j] == '(' || s[j] == '[' || s[j] == '{'){
arr[sz] = s[j];
sz++;
}
else{
if(s[j] == ')'){
if(arr[sz-1] == '(')sz--;
else {
f = 1;
break;
}
}
else if(s[j] == '}'){
if(arr[sz-1] == '{')sz--;
else {
f = 1;
break;
}
}
else if(s[j] == ']'){
if(arr[sz-1] == '[')sz--;
else {
f = 1;
break;
}
}
}
}
if(f == 1)cout << "NO\n";
else if(sz > 0)cout << "NO\n";
else cout << "YES\n";
}
return 0;
}

P1028 [NOIP 2001 普及组] 数的计算

题目描述

给出正整数 $n$,要求按如下方式构造数列:

  1. 只有一个数 $n$ 的数列是一个合法的数列。
  2. 在一个合法的数列的末尾加入一个正整数,但是这个正整数不能超过该数列最后一项的一半,可以得到一个新的合法数列。

请你求出,一共有多少个合法的数列。两个合法数列 $a, b$ 不同当且仅当两数列长度不同或存在一个正整数 $i \leq |a|$,使得 $a_i \neq b_i$。

输入格式

输入只有一行一个整数,表示 $n$。

输出格式

输出一行一个整数,表示合法的数列个数。

输入输出样例 #1

输入 #1

1
2
6

输出 #1

1
2
6

说明/提示

样例 1 解释

满足条件的数列为:

  • $6$
  • $6, 1$
  • $6, 2$
  • $6, 3$
  • $6, 2, 1$
  • $6, 3, 1$

数据规模与约定

对于全部的测试点,保证 $1 \leq n \leq 10^3$。

说明

本题数据来源是 NOIP 2001 普及组第一题,但是原题的题面描述和数据不符,故对题面进行了修改,使之符合数据。原题面如下,谨供参考:

我们要求找出具有下列性质数的个数(包含输入的正整数 $n$)。

先输入一个正整数 $n$($n \le 1000$),然后对此正整数按照如下方法进行处理:

  1. 不作任何处理;
  2. 在它的左边拼接一个正整数,但该正整数不能超过原数,或者是上一个被拼接的数的一半;
  3. 加上数后,继续按此规则进行处理,直到不能再加正整数为止。

感谢 @dbxxx 对本题情况的反馈,原题面的问题见本贴


这是一道十分纯正的数学问题

如果你是高中生,一定能想到这就是排列组合问题

逻辑

根据题目我们可以知道,每个数都有两种状态

  • 同级平移
  • 延伸

比如说样例 6

作为根数字它必须延伸(其他数字则可以自由选择延伸或不延伸)

根据说明
在一个合法的数列的末尾加入一个正整数,但是这个正整数不能超过该数列最后一项的一半,可以得到一个新的合法数列

  • 那么延伸的第一种可能我们就定为floor(i/2)
    • 这样就变成了6->3
  • 根据这个说明第二种延伸可能我们就定为floor(i/2)-1
    • 这样就变成了6->2
    • 这个同时也可以看作3的同级平移
  • 同理6->3还可以延展为6->3->1
  • 同时我们还可以发现i=1既不能继续延伸也不能同级平移
    • 所以我们将i=1作为边界条件
    • 其他数字则用递推获取

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <bits/stdc++.h>
using namespace std;
int solve(int b){
if(b == 1)return 1;
int res = 1;
for(int i = 1;i<=floor(b/2);i++)
res += solve(i);
return res;
}
int main(){
int R;
cin >> R;
cout << solve(R);
return 0;
}

这样是不是就得了?提交代码后发现超时了

我们发现,每一个数字产生的种类只与i有关而与它的父节点无关

所以我们可以用一个数组记录结果,这样就可以避免重复计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <bits/stdc++.h>
using namespace std;
int arr[1001];
int solve(int b){
if(arr[b] != -1)return arr[b];
int res = 1;
for(int i = 1;i<=floor(b/2);i++)
res += solve(i);
arr[b] = res;
return res;
}
int main(){
int R;
for(int i = 0;i<1001;i++)arr[i] = -1;
arr[1] = 1;
cin >> R;
cout << solve(R);
return 0;
}

P1015 [NOIP 1999 普及组] 回文数

题目描述

若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。

例如:给定一个十进制数 $56$,将 $56$ 加 $65$(即把 $56$ 从右向左读),得到 $121$ 是一个回文数。

又如:对于十进制数 $87$:

STEP1:$87+78=165$
STEP2:$165+561=726$
STEP3:$726+627=1353$
STEP4:$1353+3531=4884$

在这里的一步是指进行了一次 $N$ 进制的加法,上例最少用了 $4$ 步得到回文数 $4884$。

写一个程序,给定一个 $N$($2 \le N \le 10$ 或 $N=16$)进制数 $M$($100$ 位之内),求最少经过几步可以得到回文数。如果在 $30$ 步以内(包含 $30$ 步)不可能得到回文数,则输出 Impossible!

输入格式

两行,分别是 $N$,$M$。

输出格式

如果能在 $30$ 步以内得到回文数,输出格式形如 STEP=ans,其中 $\text{ans}$ 为最少得到回文数的步数。

否则输出 Impossible!

输入输出样例 #1

输入 #1

1
2
3
10
87

输出 #1

1
2
STEP=4


处理思路

读入

首先,我们使用cin去将输入数据储存到int Nstring M中,

之所以使用string M是因为M.size()可以很方便的获取字符长度

以便后续转移到数组中

转移

得到字符串之后,我们还需要补位,

即最终结果可能有110位,输入的有3位,

我们也要把有效数字前的107位补上

(虽然后续操作也要逆过来找有效数字,但是这样做可以避免进位操作时未指定元素初始值而导致的错误)

while(M.size() < 110)M = '0' + M;

之后使用

1
2
3
4
5
6
for(int i = 0;i<110;i++){
if(M[i] >= '0' && M[i] <= '9')
arr[i] = M[i] - '0';
else
arr[i] = M[i] - 'A' + 10;
}

将字符串转移到int arr[110]

其中对Ascii码值操作可以将字符转为对应数组

判断

这个功能是核心,用来判断每一步之后的数字是不是回文数

1
2
3
4
5
6
7
8
9
10
11
12
13
bool check(){
//由于补有0,所以要寻找有效数字
int f = -1;
for(int i = 0;i<110;i++){
if(arr[i] != 0 && f == -1)f = i;
if(f != -1 && arr[109 - (i-f)] != arr[i]){//直接对ascill进行比较
return false;
//找到不对称的马上给出否定结果并跳出
}
}
return true;
//没有找到不对称的给出肯定结果
}

模拟计算捕捉

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void _step(){//step与万能头里的函数重名了
int brr[110];
for(int i = 0;i<110;i++){
brr[i] = arr[i];
}
//先记录初始的值
int f = -1;//找有效数字
for(int j = 0;j<110;j++){
if(brr[j] != 0 && f == -1)f = j;
if(f != -1){
arr[109 - (j-f)] += brr[j];
//逐位运算
}
}
for(int k = 109;k>0;k--){
arr[k-1] += arr[k] / N;
arr[k] = arr[k] % N;
//根据N进行进位
// cout << arr[k] << endl;
}
res++;
//步骤数+1
}

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <bits/stdc++.h>
using namespace std;
int arr[110],N,res = 0,step = 0;
string M;
bool check(){
int f = -1;
for(int i = 0;i<110;i++){
if(arr[i] != 0 && f == -1)f = i;
if(f != -1 && arr[109 - (i-f)] != arr[i]){
return false;
}
}
return true;
}
void _step(){
int brr[110];
for(int i = 0;i<110;i++){
brr[i] = arr[i];
}
int f = -1;
for(int j = 0;j<110;j++){
if(brr[j] != 0 && f == -1)f = j;
if(f != -1){
arr[109 - (j-f)] += brr[j];
}
}
for(int k = 109;k>0;k--){
arr[k-1] += arr[k] / N;
arr[k] = arr[k] % N;
// cout << arr[k] << endl;
}
res++;
}
int main(){
cin >> N >> M;
while(M.size() < 110)M = '0' + M;
// cout << M;
for(int i = 0;i<110;i++){
if(M[i] >= '0' && M[i] <= '9')
arr[i] = M[i] - '0';
else
arr[i] = M[i] - 'A' + 10;
}
for(int j = 0;j<30;j++){
_step();
if(check() == true){
cout << "STEP=" << res;
return 0;
}
}
cout << "Impossible!";
return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <bits/stdc++.h>
using namespace std;
string bigAdd(string a,string b){
int cr[4001];
string res = "";
while(a.size()>b.size())
b = '0' + b;
while(b.size()>a.size())
a = '0' + a;
for(int i = 0;i<4001;i++)
cr[i] = 0;
for(int i = a.size()-1;i>=0;i--){
cr[i] += (a[i]-'0')+(b[i]-'0');
if(i > 0){
cr[i-1] += cr[i]/10;
cr[i] = cr[i]%10;
}
}
int f = 0;
for(int i = 0;i<a.size();i++){
if(f == 0 && cr[i] != 0)f = 1;
if(f == 1){
if(i == 0 && cr[i] >= 10){
res += cr[i] / 10 + '0';
cr[i] = cr[i] % 10;
}
res += cr[i] + '0';
}
}
if(f == 0)return "0";
return res;
}
string smallMulti(string a,int b){
int cr[4001];
string res = "";
for(int i = 0;i<4001;i++)
cr[i] = 0;
for(int i = a.size()-1;i>=0;i--){
cr[i] += (a[i]-'0')*b;
if(i > 0){
cr[i-1] += cr[i]/10;
cr[i] = cr[i]%10;
}
}
int f = 0;
for(int i = 0;i<a.size();i++){
if(f == 0 && cr[i] != 0)f = 1;
if(f == 1){
if(i == 0 && cr[i] >= 10){
res += cr[i] / 10 + '0';
cr[i] = cr[i] % 10;
}
res += cr[i] + '0';
}
}
if(f == 0)return "0";
return res;
}
int main(){
string a,b,res = "0";
cin >> a >> b;
for(int i = 0;i<b.size();i++){
string c = smallMulti(a,b[i]-'0');
for(int j = 0;j<b.size()-1-i;j++)
c += '0';
res = bigAdd(res,c);
}
cout << res;
return 0;
}

躲猫猫结束咯(麦小鼠音)

1.在输入框输入

1
/scoreboard objectives add number1 dummy number1

2.循环 无条件 保持开启

1
/scoreboard players set @a number1 -1

3.连锁 无条件 保持开启(被2所指)

1
/execute as @e at @s run scoreboard players add @a[r=16] number1 1

16表示范围,可修改

4.连锁 无条件 保持开启(被3所指)

1
/titleraw @a actionbar {"rawtext": [{"text": "§6附近实体数: §a"}, {"score":{"name": "@s","objective": "number1"}}]}

不是怎么老贝炸啊TAT

演示视频:

1.循环 无条件 保持开启

1
/execute as @e[type=chicken] at @s run tp @s ~~~

chicken 表示代表的实体,可替换

2.循环 无条件 保持开启

1
/execute as @e[type=chicken] at @s if entity @a[r=3] run damage @e 10 block_explosion

3 表示触发范围,
10 表示伤害

这里是一些最常用的 Hexo 命令了

启动服务器

1
$ hexo server

自动生成文章

1
$ hexo generate --watch

将 Hexo 推送到 github

1
$ hexo deploy
0%